在正则表达式中捕获组的奇怪行为

时间:2016-02-19 15:46:20

标签: python regex

给出以下简单的正则表达式,其目标是在引号字符之间捕获文本:

regexp = '"?(.+)"?'

当输入类似于:

"text"

捕获组(1)具有以下内容:

text"

我希望组(1)只有text(没有引号)。有人可以解释发生了什么以及为什么正则表达式捕获"符号,即使它在捕获组#1之外。我不理解的另一个奇怪的行为是为什么第二个引用字符被捕获但不是第一个引用字符,因为它们都是可选的。最后我使用以下正则表达式修复它,但我想了解我做错了什么:

regexp = '"?([^"]+)"?'

5 个答案:

答案 0 :(得分:3)

Quantifiers in regular expressions are greedy:他们尝试尽可能多地匹配文字。由于您的上一个"是可选的(您在正则表达式中写了"?),因此.+会匹配它。

使用[^"]是一种可接受的解决方案。缺点是你的字符串不能包含"个字符(根据具体情况,可能是也可能不是这样)。

另一个是要求"

regexp = '"(.+)"'

另一个是使用+使+?非贪婪。但是,您还需要添加锚点^$(或类似的,具体取决于上下文),否则它只会匹配第一个字符t {{1} }}):

"test"

此正则表达式允许regexp = '^"?(.+?)"?$' 个字符位于字符串的中间,因此"将导致该组捕获"t"e"s"t"

答案 1 :(得分:1)

。+贪婪。它将收集包括"在内的所有内容。你的决赛"?并不要求报价存在,因此。+包括报价。

第一个引用未被捕获,因为它与"?相匹配

答案 2 :(得分:1)

  

为什么正则表达式捕获“符号,即使它在捕获组#1之外

"?(.+)"?模式包含greedy dot matching子模式。 .也可以与"匹配。 "?可选子模式。这意味着如果前一个子模式是贪婪的(并且.+是一个贪婪的子模式)并且可以匹配后续子模式(并且.可以匹配"),那么.+将接替该可选值。

negated character class是匹配任何字符的正确方法,但是匹配特定的一个/范围的字符。 [^"]永远不会与"匹配,因此最后"永远不会与此模式匹配。

  

为什么第二个引号字符被捕获但不是第一个引用字符,因为它们都是可选的

第一个"?出现在贪婪点匹配模式之前。引擎会看到"(如果它在字符串中)并将引号与第一个"?匹配。

答案 3 :(得分:0)

默认情况下,regexp是贪婪的,它会尽快尽量匹配。

由于您的捕获组包含.+,因此它将匹配"?之前的结束括号。然后,当退出组时,它位于您的行的末尾,与可选的"匹配。

答案 4 :(得分:0)

.+只要可以匹配任何字符(包括")。当它到达输入的末尾时,"?匹配,因为这意味着"是可选的。

你应该使用“非贪婪”:

regex "(.+?)"