-2

I have to manage all the possible home automation commands that I say to my voice assistant, some examples can be:

  1. "accendi la luce in corridoio, spegni la luce in camera e imposta 20 in salotto"
  2. "accendi la luce in camera e cameretta, spegni la luce in corridoio"
  3. "accendi la luce in salotto"

With a single regular expression I must be able to subdivide each type of command:

  1. ("accendi la luce in corridoio, ", "spegni la luce in camera e ", "imposta 20 in salotto")
  2. ("accendi la luce in camera e cameretta, ", "spegni la luce in corridoio")
  3. ("accendi la luce in salotto")

Using the regular expression from my previous question modified for the use I have to make of it, I get:

>>> print(re.search(r'(accendi.+)(spegni.+)(imposta.+)', "accendi la luce in corridoio, spegni la luce in camera e imposta 20 in salotto").groups())  
('accendi la luce in corridoio, ', 'spegni la luce in camera e ', 'imposta 20 in salotto')

This is OK, but not for these other commands:

>>> print(re.search(r'(accendi.+)(spegni.+)(imposta.+)', "accendi la luce in camera e cameretta, spegni la luce in corridoio").groups())  
Traceback (most recent call last):  
  File "<stdin>", line 1, in <module>  
AttributeError: 'NoneType' object has no attribute 'groups'  
>>> print(re.search(r'(accendi.+)(spegni.+)(imposta.+)', "accendi la luce in salotto").groups())
Traceback (most recent call last):  
  File "<stdin>", line 1, in <module>  
AttributeError: 'NoneType' object has no attribute 'groups'  
jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
  • 1
    [`|`](https://www.regular-expressions.info/alternation.html) – Olvin Roght Feb 13 '20 at 07:26
  • >>> print(re.search(r'(accendi.+)|(spegni.+)|(imposta.+)', "accendi la luce in camera e cameretta, spegni la luce in corridoio").groups()) ('accendi la luce in camera e cameretta, spegni la luce in corridoio', None, None) – Oscar Cappa Feb 13 '20 at 07:30
  • It appears that you neither upvoted nor accepted the answer to your previous question that contained the information you needed. Please read https://stackoverflow.com/help/someone-answers. – jonrsharpe Feb 13 '20 at 07:31
  • thanks jonrsharpe, the answer to my previous question is correcty for the previous use, now I added shutters, doors and air conditioners. – Oscar Cappa Feb 13 '20 at 07:36

1 Answers1

0

Try this regex. It does not require all three delimiters to exist, but, if they do, the command will be properly split:

(accendi(?:(?!spegni).)+)(spegni(?:(?!imposta).)+)?(imposta.+)?

(accendi         #start first group, match accendi
   (?:           #start non-capturing group
      (?!        #start negative lookahead
         spegni  #ensure the next characters aren't spegni
      )          #end negative lookahead
      .          #match any character
   )+            #end non-capturing group, repeat 1 or more times
)                #end first capture group
(spegni          #start second group, match spegni
   (?:           #start non-capturing group
      (?!        #start negative lookahead
         imposta #ensure the next characters aren't imposta
      )          #end negative lookahead
      .          #match any character
   )+            #end non-capturing group, repeat 1 or more times
)?               #end second capture group, make it optional
(imposta         #start third capture group, match imposta
   .+            #match anything 1 or more times
)?               #end third capture group, make optional
Zaelin Goodman
  • 896
  • 4
  • 11