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

rka*_*ach 5 python regex

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

regexp = '"?(.+)"?'
Run Code Online (Sandbox Code Playgroud)

当输入是这样的:

"text"
Run Code Online (Sandbox Code Playgroud)

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

text"
Run Code Online (Sandbox Code Playgroud)

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

regexp = '"?([^"]+)"?'
Run Code Online (Sandbox Code Playgroud)

Wik*_*żew 2

解决方案

regexp = '^"?(.*?)"?$'
Run Code Online (Sandbox Code Playgroud)

或者,如果正则表达式引擎允许环视

regexp = '(?<=^"?).*?(?="?$)'
Run Code Online (Sandbox Code Playgroud)

细节

  • ^- 字符串的开头
  • "?- 一个可选的"字符
  • (.*?)- 第 1 组:除换行符之外的任何零个或多个字符尽可能少
  • "?- 一个可选的"字符
  • $- 字符串末尾。 解释

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

"?(.+)"?模式包含一个贪婪点匹配子模式。A也.可以匹配 a 。""?是一个可选的子模式。这意味着如果前一个子模式是贪婪的(并且.+是贪婪的子模式)并且可以匹配后续的子模式(并且.可以匹配 a "),则将.+接管该可选值。

否定字符类是匹配除特定一个/多个字符之外的任何字符的正确方法。[^"]永远不会匹配 a ",因此最后一个"永远不会与此模式匹配。

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

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