58 votes

Comment diviser de longues règles d'expression régulière en plusieurs lignes en Python

Est-ce réellement faisable ? J'ai de très longues règles de modèle de regex qui sont difficiles à comprendre car elles ne rentrent pas immédiatement dans l'écran. Exemple:

 test = re.compile('(?P<full_path>.+):\d+:\s+warning:\s+Member\s+(?P<member_name>.+)\s+\((?P<member_type>%s)\) of (class|group|namespace)\s+(?P<class_name>.+)\s+is not documented' % (self.__MEMBER_TYPES), re.IGNORECASE)

La barre oblique inverse ou les guillemets triples ne fonctionneront pas.

ÉDITER. J'ai fini par utiliser le mode VERBOSE. Voici à quoi ressemble le modèle d'expression régulière maintenant :

 test = re.compile('''
  (?P<full_path>                                  # Capture a group called full_path
    .+                                            #   It consists of one more characters of any type
  )                                               # Group ends                      
  :                                               # A literal colon
  \d+                                             # One or more numbers (line number)
  :                                               # A literal colon
  \s+warning:\s+parameters\sof\smember\s+         # An almost static string
  (?P<member_name>                                # Capture a group called member_name
    [                                             #   
      ^:                                          #   Match anything but a colon (so finding a colon ends group)
    ]+                                            #   Match one or more characters
   )                                              # Group ends
   (                                              # Start an unnamed group 
     ::                                           #   Two literal colons
     (?P<function_name>                           #   Start another group called function_name
       \w+                                        #     It consists on one or more alphanumeric characters
     )                                            #   End group
   )*                                             # This group is entirely optional and does not apply to C
   \s+are\snot\s\(all\)\sdocumented''',           # And line ends with an almost static string
   re.IGNORECASE|re.VERBOSE)                      # Let's not worry about case, because it seems to differ between Doxygen versions

71voto

naeg Points 1737

Vous pouvez diviser votre modèle regex en citant chaque segment. Aucune barre oblique inverse nécessaire.

 test = re.compile(('(?P<full_path>.+):\d+:\s+warning:\s+Member'
                   '\s+(?P<member_name>.+)\s+\((?P<member_type>%s)\) '
                   'of (class|group|namespace)\s+(?P<class_name>.+)'
                   '\s+is not documented') % (self.__MEMBER_TYPES), re.IGNORECASE)

Vous pouvez également utiliser l'indicateur de chaîne brute 'r' et vous devrez le mettre avant chaque segment.

Voir la doc .

2voto

stema Points 36113

Utilisez soit la concaténation de chaînes comme dans la réponse de naeg, soit re.VERBOSE/re.X, mais attention, cette option ignorera les espaces et les commentaires. Vous avez des espaces dans votre regex, ils seraient donc ignorés et vous devez soit les échapper, soit utiliser \s

Donc par exemple

 test = re.compile("""(?P<full_path>.+):\d+: # some comment
    \s+warning:\s+Member\s+(?P<member_name>.+) #another comment
    \s+\((?P<member_type>%s)\)\ of\ (class|group|namespace)\s+
    (?P<class_name>.+)\s+is\ not\ documented""" % (self.__MEMBER_TYPES), re.IGNORECASE | re.X)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X