如何在python中把多个regex合并成一个?

36 人关注

我正在学习正则表达式。我不知道如何将不同的正则表达式组合成一个单一的通用正则表达式。

我想写一个适用于多种情况的单一正则表达式。我知道这可以用天真的方法来完成,即使用 or " | " 经营者。

我不喜欢这种方法。谁能告诉我更好的方法?

python
regex
pattern-matching
Amit
Amit
发布于 2017-02-09
4 个回答
Lior Magen
Lior Magen
发布于 2021-12-24
已采纳
0 人赞同

你需要编译所有的regex函数。看看这个例子。

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]
for sentence in sentences:
    generic_re = re.compile("(%s|%s|%s|%s)" % (re1, re2, re3, re4)).findall(sentence)
    
@Amit 我已经解决了这个问题。我使用了你写的变量名 "generic-re",它导致了这个错误。
Toto
只有一个元素的字符类是无稽之谈,会使重码更难读。
谢谢你的工作!我得到了这个问题的答案 stackoverflow.com/questions/53947401/...
变量 sentence 没有定义+ findall 需要一个字符串而不是一个列表。也许你是想做 for sentence in sentences
另见 stackoverflow.com/a/36870447/288875 以确认 | 运算符实际上具有最低的优先权(即它比任何其他可能用于 re1 ... re4 的运算符具有 "较弱的约束力")。
nigel222
nigel222
发布于 2021-12-24
0 人赞同

要想用一系列任意的REs来 findall ,你所要做的就是把每个REs返回的匹配列表连接起来。

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) )
    
你确定上述方法有效吗?我只是通过复制和粘贴得到 'str' object has no attribute 'findall'
@gented 我犯了一个愚蠢的错误,除了re,任何变量的名字都是你导入的!我将编辑我的答案。我将编辑我的答案。
Karen McCulloch
Karen McCulloch
发布于 2021-12-24
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)

替换代码1】是一种展望。

如果...匹配下一个,但不消耗任何字符串。这被称为 "前瞻断言"。例如,Isaac (?=Asimov)只有在 "Asimov "之后才会匹配 "Isaac"。

替换代码2 在字符串的任何地方找到一个数字,后面有一个p,并将该数字命名为 "梨"

起初我不明白你说的 "似乎只与第一个实例相匹配 "是什么意思,但后来我意识到你是在寻找 first 在一个过程中匹配多个词组,而非 every 这是个有趣的问题,很好的解决方案。但我不确定你是如何从 group(0) 中得到 '10a,11p' 的,当我运行它时,只给了我 ''
hansrajswapnil
hansrajswapnil
发布于 2021-12-24
0 人赞同

你可能不需要编译这两个regex模式。这里有一个方法,让我们看看它是否对你有效。

>>> import re
>>> text = 'aaabaaaabbb'
>>> A = 'aaa'
>>> B = 'bbb'