我遇到了这个有趣的案例。我不确定|的优先级运算符所以我最初使用非捕获组来分隔我的管道。但是,这导致匹配为“无”,删除捕获组也会导致“无”。但是,指定它们周围的单个捕获组是有效的。这对我来说很奇怪。我不太明白发生了什么。有什么想法吗?
此外,搜索适用于所有情况,正如我所期望的那样......
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>
答案 0 :(得分:3)
您的表达式^Details: WARNING|CRITICAL|ERROR
被解释为这三个正则表达式的替换:
^Details: WARNING
CRITICAL
ERROR
由于re.match
(与re.search
不同)要求匹配从字符串的开头开始,因此无法匹配Details: CRITICAL
和Details: 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
希望能回答你所有问题!