我的正则表达式:
(?si)\bStart\b(.*?)\bError\b(.*?)\bEnd\b
适用于以下情况:
stuff happens
Start
stuff happens
Error
stuff happens
End
但也匹配Error
和Start
序列之外的End
:
Start
End
Error
Start
End
当条件变为情景#2时,如何仅匹配第一个示例中的匹配?
答案 0 :(得分:2)
PowerShell,使用负面预测并假设"内容发生"零件永远不会包含单词" start"或者"结束":
$txt = Get-Content file.txt | Out-String
$pattern = "(?si)\bStart\b((?!\bEnd\b).)*?\bError\b((?!\bStart\b).)*?\bEnd\b"
$regex = New-Object System.Text.RegularExpressions.Regex($pattern)
$regex.Matches($txt)
解释here。
答案 1 :(得分:2)
Alexander's answer可能已经足够好了,但我会这样做:
(?si)\bStart\b(?:(?!\b(?:Start|End)\b).)*\bError\b(?:(?!\b(?:Start|End)\b).)*\bEnd\b
这个正则表达式的主要优点是它失败得更快。 ((?!\bStart\b).)*?
如果有End
您希望有Start
可以正常工作,但如果无法匹配,它仍然必须一直到下一个(?si)\bStart\b(?>(?:(?!\b(?:Start|End|Error)\b).)*)\bError\b(?>(?:(?!\b(?:Start|End|Error)\b).)*)\bEnd\b
(如果有的话)或者在文件结束之前它可以放弃比赛。
事实上,你可以更进一步,完全消除回溯:
Error
添加Start
替代方案并将该部分封装在原子组中意味着如果它找到Error
并且没有之前找到End
下一个$regex = [regex] '(?si)\bStart\b(?>(?:(?!\b(?:Start|End|Error)\b).)*)\bError\b(?>(?:(?!\b(?:Start|End|Error)\b).)*)\bEnd\b'
$matchdetails = $regex.Match($subject)
while ($matchdetails.Success) {
# matched text: $matchdetails.Value
# match start: $matchdetails.Index
# match length: $matchdetails.Length
$matchdetails = $matchdetails.NextMatch()
}
,它会立即失败。
这是一个PowerShell示例(由RegexBuddy生成):
Error
更新:我刚刚意识到我不应该将Start..End
分支添加到第二个轮换中。我的正则表达式只匹配那些包含Error
的{{1}}块只有一次,这可能太具体了。此版本匹配至少一次出现Error
的块:
(?si)\bStart\b(?>(?:(?!\b(?:Start|End|Error)\b).)*)\bError\b(?>(?:(?!\b(?:Start|End)\b).)*)\bEnd\b
答案 2 :(得分:0)
好吧,所以在我能够理解接受的答案是逐步逐步完成之后我又回到了这一点,这对我来说比一行中的所有内容都更容易理解。这个替代答案解释了从开始到结束的过程,原始问题的目标是按顺序采用3匹配模式,并确保不会发生不良匹配。
第1步:在添加排除项之前使您的模式正常工作
\bStart\b.*\bError\b.*\bEnd\b
第2步:放置非捕获组,检查任何类型的字符,同时移动其中的.
。这些非捕获组(?:.)
现在只是占位符,意味着它们将检查任何字符,因此它不会破坏我们已经建立的模式。
\bStart\b(?:.)*\bError\b(?:.)*\bEnd\b
第3步:现在我们要将那些非捕获组封装在一个正向预测中,它在非捕获组内部是一个负向前瞻,所以我们知道如果它检测到Start,End,则提前失败或者最后一个错误。如果不打破最小匹配功能,我们就无法真正打破这一点。
\bStart\b(?>(?:(?!\b(Start|End|Error)\b).))*\bError\b(?>(?:(?!\b(Start|End)\b).))*\bEnd\b
第4步:现在,只需在开头添加行匹配过滤器,就可以了!
(?si)\bStart\b(?>(?:(?!\b(Start|End|Error)\b).))*\bError\b(?>(?:(?!\b(Start|End)\b).))*\bEnd\b
我是一个高度视觉化的学习者,所以我正在分享一个个人帮助我分解它的图形。