2017-02-09 5 views
0

Я узнаю о регулярном выражении. У меня нет идеи, как объединить различные регулярные выражения, чтобы сделать одно общее регулярное выражение.Как объединить несколько регулярных выражений в один в python?

Я хочу написать одно регулярное выражение, которое для множества случаев. Я знаю, что это можно сделать с наивным подходом, используя или«|» оператор.

Мне не нравится этот подход. Может ли кто-нибудь сказать мне лучший подход?

+0

Plz принимает мой ответ, если он работает для вас. –

ответ

2

Вам необходимо скомпилировать все ваши функции регулярных выражений. Проверьте этот пример:

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) 
+0

@ Примите Iv'e это исправлено. Я использовал имя переменной, которое вы написали «generic-re», и это вызвало ошибку. –

+0

Класс символов только с одним элементом - это абсурд и сделать regex труднее для чтения. – Toto

1

Для findall с произвольной последовательностью все вы должны сделать УЭ сцепить список матчей, которые каждый возвращается:

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 re in re_list: 
    matches += re.findall(re, string) 

Для повышения эффективности было бы лучше использовать список скомпилированных RE.

В качестве альтернативы вы можете присоединиться строки элемента RE с помощью

generic_re = re.compile('|'.join(re_list)) 
0

Я вижу много людей используют трубы, но это, кажется, соответствует только первый экземпляр. Если вы хотите совместить все, попробуйте использовать lookaheads.

Пример:

>>> 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' 

(?= ...) это взгляд в будущее:

Срабатывает, если ... соответствует следующему, но не потребляет строки. Это называется ожидаемым утверждением. Например, Исаак (? = Азимов) будет соответствовать «Исааку», только если за ним последует «Азимов».

.*?(?P<pears>\d+)p найти ряд следует р где-нибудь в строке и назовите номер «грушу»