首页 > 解决方案 > 在 Python 中组合多个正则表达式

问题描述

为清楚起见,我正在寻找一种方法来一次编译多个正则表达式。为简单起见,假设每个表达式都应采用 format (.*) something (.*)。要测试的表达式不超过 60 个。

如此处所见,我终于写了以下内容。

import re
re1 = r'(.*) is not (.*)'
re2 = r'(.*) is the same size as (.*)'
re3 = r'(.*) is a word, not (.*)'
re4 = r'(.*) is world know, not (.*)'

sentences = ["foo2 is a word, not bar2"]

for sentence in sentences:
    match = re.compile("(%s|%s|%s|%s)" % (re1, re2, re3, re4)).search(sentence)
    if match is not None:
        print(match.group(1))
        print(match.group(2))
        print(match.group(3))

由于正则表达式由管道分隔,我认为一旦匹配规则,它将自动退出。

执行代码,我有

foo2 is a word, not bar2
None
None

但是通过在 re.compile 中反转 re3 和 re1 match = re.compile("(%s|%s|%s|%s)" % (re3, re2, re1, re4)).search(sentence),我有

foo2 is a word, not bar2
foo2
bar2

据我所知,第一个规则被执行,但其他规则不被执行。有人可以为我指出这个案子的正确方向吗?

亲切的问候,

标签: pythonregex

解决方案


您的示例存在各种问题:

  1. 您正在使用捕获组,因此它会获取1您希望引用第一组内部正则表达式的索引。请改用非捕获组(?:%s|%s|%s|%s)
  2. 组内索引甚至增加|。所以(?:(a)|(b)|(c))你会得到:

    >>> re.match(r'(?:(a)|(b)|(c))', 'a').groups()
    ('a', None, None)
    >>> re.match(r'(?:(a)|(b)|(c))', 'b').groups()
    (None, 'b', None)
    >>> re.match(r'(?:(a)|(b)|(c))', 'c').groups()
    (None, None, 'c')
    

    似乎您希望只有一个组 1 返回或者返回ab或者c取决于分支......不,索引是按从左到右的顺序分配的,而不考虑正则表达式的语法。

regex模块通过对组进行编号来满足您的需求。如果你想使用内置模块,你将不得不忍受这样一个事实,即如果你使用命名组,正则表达式的不同分支之间的编号是不一样的:

>>> import regex
>>> regex.match(r'(?:(?P<x>a)|(?P<x>b)|(?P<x>c))', 'a').groups()
('a',)
>>> regex.match(r'(?:(?P<x>a)|(?P<x>b)|(?P<x>c))', 'b').groups()
('b',)
>>> regex.match(r'(?:(?P<x>a)|(?P<x>b)|(?P<x>c))', 'c').groups()
('c',)

(尝试使用该正则表达式re会导致重复组出错)。


推荐阅读