web-dev-qa-db-fra.com

Comment combiner plusieurs regex en une seule en python?

J'apprends l'expression régulière. Je ne sais pas comment combiner différentes expressions régulières pour créer une seule expression régulière générique.

Je veux écrire une seule expression régulière qui fonctionne pour plusieurs cas. Je sais que cela peut être fait avec une approche naïve en utilisant l'opérateur o"|".

Je n'aime pas cette approche. Quelqu'un peut-il me dire une meilleure approche?

15
Amit

Vous devez compiler toutes vos fonctions d'expression régulière. Vérifiez cet exemple:

import re
re1 = r'\d+\.\d*[L][-]\d*\s[A-Z]*[/]\d*'
re2 = '\d*[/]\d*[A-Z]*\d*\s[A-Z]*\d*[A-Z]*'
re3 = '[A-Z]*\d+[/]\d+[A-Z]\d+'
re4 = '\d+[/]\d+[A-Z]*\d+\s\d+[A-z]\s[A-Z]*'

sentences = [string1, string2, string3, string4]
generic_re = re.compile("(%s|%s|%s|%s)" % (re1, re2, re3, re4)).findall(sentence)
6
Lior Magen

Pour findall avec une série arbitraire de REs tout ce que vous avez à faire est de concaténer la liste des correspondances que chacun retourne:

re_list = [
    '\d+\.\d*[L][-]\d*\s[A-Z]*[/]\d*', # re1 in question,
    ...
    '\d+[/]\d+[A-Z]*\d+\s\d+[A-z]\s[A-Z]*', # re4 in question
]

matches = []
for r in re_list:
   matches += re.findall( r, string)

Pour plus d'efficacité, il serait préférable d'utiliser une liste d'ER compilés.

Vous pouvez également joindre les chaînes RE de l'élément à l'aide de

generic_re = re.compile( '|'.join( re_list) )
1
nigel222

Je vois que beaucoup de gens utilisent des tuyaux, mais cela ne semble correspondre qu'à la première instance. Si vous souhaitez faire correspondre tous les éléments, essayez d'utiliser les recherches.

Exemple:

>>> fruit_string = "10a11p" 
>>> fruit_regex = r'(?=.*?(?P<pears>\d+)p)(?=.*?(?P<apples>\d+)a)'
>>> re.match(fruit_regex, fruit_string).groupdict()
{'apples': '10', 'pears': '11'}
>>> re.match(fruit_regex, fruit_string).group(0)
'10a,11p'
>>> re.match(fruit_regex, fruit_string).group(1)
'11'

(?= ...) Est un aperçu:

Correspond si ... correspond à la suivante, mais ne consomme aucune chaîne. Cela s'appelle une assertion d'anticipation. Par exemple, Isaac (? = Asimov) ne correspondra à "Isaac" que s'il est suivi de "Asimov".

.*?(?P<pears>\d+)p trouver un nombre suivi d'un p n'importe où dans la chaîne et nommer le nombre "poires"

0
Karen McCulloch