你能解释一下这个正则表达式为什么不起作用吗?

2024-06-17 18:23:17 发布

您现在位置:Python中文网/ 问答频道 /正文

>>> d = "Batman,Superman"
>>> m = re.search("(?<!Bat)\w+",d)
>>> m.group(0)
'Batman'

为什么组(0)不匹配超人?This lookaround tutorial说:

(?<!a)b matches a "b" that is not preceded by an "a", using negative lookbehind


Tags: researchthatisgroupnotthistutorial
3条回答

根据手册:

Patterns which start with negative lookbehind assertions may match at the beginning of the string being searched.

http://docs.python.org/library/re.html#regular-expression-syntax

Batman不是在前面直接加上Bat,因此它首先匹配。事实上,Superman;字符串中的中间有一个逗号,可以很好地匹配RE,但无论如何都不匹配,因为可以在字符串的前面匹配。在

也许这可以更好地解释:如果字符串是Batman,并且您开始尝试从m进行匹配,那么RE直到后面的字符才会匹配(给出一个匹配的an),因为这是字符串中唯一以Bat开头的地方。在

从一个简单的字符串到一个简单的正则表达式(从一个简单的字符串到一个匹配的字符串,从一个简单的字符串开始向左边移动)。在lookaround的情况下,在光标的每一个停止处,lookaround被断言,如果为true,引擎将继续尝试匹配。一旦引擎能匹配你的模式,它就会返回匹配。在

在字符串的位置0(即,Batman中的B之前),断言成功,因为Bat在当前位置之前不存在,因此,\w+可以匹配整个单词{}(记住,regex本质上是贪婪的-即,将尽可能匹配)。在

请参阅this page以获取有关引擎内部结构的更多信息。在


为了达到你想要的效果,你可以使用类似于:

\b(?!Bat)\w+

在此模式中,引擎将匹配word boundary\b1,后跟一个或多个单词字符,并声明单词字符不以Bat开头。使用lookahead而不是lookbehind,因为在这里使用lookbehind会有与原始模式相同的问题;它会在单词边界后面的位置之前查找,并且已经确定光标前面的位置是单词边界,消极的回头看总是成功的。在

1注意单词边界匹配\w和{}之间的边界(即[A-Za-z0-9_]和任何其他字符之间;它还匹配^和{}anchors)。如果你的边界需要更复杂,你需要一种不同的方式来锚定你的模式。在

相关问题 更多 >