我正在学习正则表达式。我不知道如何组合不同的正则表达式来制作单一的通用正则表达式。
我想为多个案例编写一个正则表达式。我知道这可以通过使用或 “|”运算符以天真的方式完成。
我不喜欢这种做法。任何人都可以告诉我更好的方法吗?
答案 0 :(得分:7)
您需要编译所有正则表达式函数。检查此示例:
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)
答案 1 :(得分:1)
使用任意一系列RE对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 r in re_list:
matches += re.findall( r, string)
为了提高效率,最好使用已编译的RE列表。
或者,您可以使用
加入元素RE字符串generic_re = re.compile( '|'.join( re_list) )
答案 2 :(得分: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'
(?= ...)
是展望未来:
匹配if ...匹配next,但不消耗任何字符串。这称为先行断言。例如,Isaac(?= Asimov)将匹配Isaac&#39;只有当它跟随阿西莫夫时才会出现#。
.*?(?P<pears>\d+)p
在字符串中的任意位置找到一个数字并命名数字&#34; pears&#34;