Python / Regex / Match / Search混乱

时间:2011-11-15 21:54:01

标签: python regex

我遇到了这个有趣的案例。我不确定|的优先级运算符所以我最初使用非捕获组来分隔我的管道。但是,这导致匹配为“无”,删除捕获组也会导致“无”。但是,指定它们周围的单个捕获组是有效的。这对我来说很奇怪。我不太明白发生了什么。有什么想法吗?

此外,搜索适用于所有情况,正如我所期望的那样......

re.match(r'^Details: WARNING|CRITICAL|ERROR', 'Details: CRITICAL asdfasdf')
None
re.match(r'^Details: (?:WARNING)|(?:CRITICAL)|(?:ERROR)', 'Details: CRITICAL asdfasdf
None
re.match(r'^Details: (?:WARNING|CRITICAL|ERROR)', 'Details: CRITICAL asdfasdf'
<_sre.SRE_Match at 0x1b27d98>
re.search(r'^Details: WARNING|CRITICAL|ERROR', 'Details: CRITICAL asdfasdf')
<_sre.SRE_Match at 0x1b27ed0>
re.search(r'^Details: (?:WARNING)|(?:CRITICAL)|(?:ERROR)', 'Details: CRITICAL asdfasdf')
<_sre.SRE_Match at 0x1b27e00>
re.search(r'^Details: (?:WARNING|CRITICAL|ERROR)', 'Details: CRITICAL asdfasdf')
<_sre.SRE_Match at 0x1b27e00>

3 个答案:

答案 0 :(得分:3)

您的表达式^Details: WARNING|CRITICAL|ERROR被解释为这三个正则表达式的替换:

  • ^Details: WARNING
  • CRITICAL
  • ERROR

由于re.match(与re.search不同)要求匹配从字符串的开头开始,因此无法匹配Details: CRITICALDetails: ERROR

如果您不想要捕获组,最好的解决方法是:

r'^Details: (?:WARNING|CRITICAL|ERROR)'

如果以下任何正则表达式匹配(如预期),则此表达式匹配:

  • ^Details: WARNING
  • ^Details: CRITICAL
  • ^Details: ERROR

虽然re.search在这里工作正常,但使用re.match和这个正则表达式更有意义,因为你只是在字符串的开头寻找匹配项。

答案 1 :(得分:2)

前两个是说:匹配“详细信息:警告”,或“严重”或“错误”。

第三个是说:匹配“详细信息:”,然后是“警告”,“关键”或“错误”。

搜索结果是:在字符串中查找“详细信息:警告”,“严重”或“错误”。

匹配从字符串的开头开始,这就是前两个不起作用的原因;搜索扫描整个字符串。

答案 2 :(得分:1)

我认为|元字符的优先级仅由分组结构()提供(在某种程度上,我认为字符类[]分隔符,它将其转换为文字|字符 - 但它是文字,而不是“或操作符”。

它就像Java,C / C ++,C#,JavaScript等中的短路“或”运算符(||或Visual Basic中的OrElse)。您还可以将文字字符之间的任何内容(零空格,零字符)视为具有更高优先级的“后续”“操作符” - 但这是一种延伸。

基本上,表达式^Details: WARNING|CRITICAL|ERROR被解释为:

^Details: WARNING   # assert at the beginning, then match literally "Details: WARNING"
|                   #  -OR-
CRITICAL            # match "CRITICAL"
|                   #  -OR-
ERROR               # match "ERROR"

而表达式^Details: (WARNING|CRITICAL|ERROR)被解释为:

^Details:           # assert at the beginning, then match literally "Details: "
(                   # begin capture group
  WARNING           #   match literally "WARNING"
  |                 #    -OR-
  CRITICAL          #   match literally "CRITICAL"
  |                 #    -OR-
  ERROR             #   match literally "ERROR"
)                   # end capture group

表达式^Details: (?:WARNING|CRITICAL|ERROR)的解释方式略有不同:

^Details:           # assert at the beginning, then match literally "Details: "
(?:                 # begin match (non-capturing) group
  WARNING           #   match literally "WARNING"
  |                 #    -OR-
  CRITICAL          #   match literally "CRITICAL"
  |                 #    -OR-
  ERROR             #   match literally "ERROR"
)                   # end match group

希望能回答你所有问题!