匹配但不返回两个匹配之间的正则表达式

时间:2011-02-23 19:02:51

标签: python regex

我正在尝试检索两个不同的项目,而不使用正则表达式来匹配术语:

[[A]] son of [[B]]

我认为这样可行:

\[\[[A-Za-z\s]+\]\](?:(.*son of.*))\[\[[\|,A-Za-z\s]+\]\]

但它不太合适。如何在不返回“儿子”的情况下匹配A和B?

4 个答案:

答案 0 :(得分:4)

我假设您有一个类似[[Worf]] son of [[Mogh]]的字符串,您希望从中“返回”(即匹配)[[Worf]][[Mogh]]。为此,您需要捕获要捕获的正则表达式部分(也称为“返回”)周围的组(括号)。为了不返回son of,您还需要删除其中的捕获组(嵌套在(?:...)中)。

在代码中:

>>> s = '[[Worf]] son of [[Mogh]]'
>>> p = re.compile('(\[\[[A-Za-z\s]+\]\])(?:.*son of.*)(\[\[[\|,A-Za-z\s]+\]\])')
>>> print p.match(s).groups()
('[[Worf]]', '[[Mogh]]')

如果您使用.groups()方法获取匹配的部分,您还可以将非捕获组放在.*son of.*周围,这可能会使RE更具可读性(我碰巧认为它制定意图 - 不要捕捉 - 更清楚)。

答案 1 :(得分:1)

我会回应dcrosta的回答,虽然我个人更喜欢使用命名捕获。使用命名捕获使得正则表达式本身更难以阅读,它为您提供了类似字典的捕获访问:

>>> mw_string = "[[Duras]] son of [[Ja'rod]]"
>>> son_re = re.compile('\[\[(?P<son>[^\]]+)\]\](?:.*son of.*)\[\[(?P<parent>[^\]]+)\]\]')
>>> print son_re.match(mw_string).group("son")
Duras
>>> print son_re.match(mw_string).group("parent")
Ja'rod

使用名称捕获的优点是您可能正在创建一整套各种regexen,每个regexen都有一组定义的参数,您希望以特定的有意义顺序从匹配中取出(例如,“[[Ja] 'rod]]的儿子[[Duras]]“)。

由于您看起来正在解析MediaWiki,因此使用mwlib迭代链接然后找到在其周围环境中具有“son of”的链接可能对您有用。这肯定有助于各种特殊形式的链接与这组regexen不匹配。

答案 2 :(得分:0)

请尝试以下操作:(\[\[[A-Za-z\s]+\]\])(?:.*son of.*)(\[\[[\|,A-Za-z\s]+\]\])

p = re.compile(r"(\[\[[A-Za-z\s]+\]\])(?:.*son of.*)(\[\[[\|,A-Za-z\s]+\]\])")
m = p.match("[[A]] son of [[B]]")
print m.groups()
# ('[[A]]', '[[B]]')

答案 3 :(得分:0)

>> a = "\[\[([A-Za-z]+)\]\] son of \[\[([A-Za-z]+)\]\]"
>> p = re.compile(a)
>> m = p.match("[[A]] son of [[B]]")
>> m.groups()
('A', 'B')