我正在尝试匹配一个可选的组,该组可以在任意数量的字符之前和之后。整个模式还具有必需的开始和结束匹配,但是中间匹配是可选的。
我从此开始,它在需要中间组时起作用:
string text = @"blah blah foo This is a test blah. the test does not work. bar";
string requiredBlah = @"(foo).*?(blah).*?(bar)";
Match m = Regex.Match(text, requiredBlah);
结果为“ foo”,“ blah”,“ bar”。
但是,当中间组是可选的时,我猜想正则表达式引擎的机制倾向于不匹配中间组。
string optionalBlah = @"(foo).*?(blah)?.*?(bar)";
结果:“ foo”,“”,bar“。
这样的回答说,如果在可选组之前和之后存在定界符,那么我可以捕获中间的可选组,但这不是我的情况。
我可以完全跳过可选组并使用string.Contains("blah")
,但是我想知道是否存在针对此类问题的纯正则表达式解决方案。我的目标是设计匹配具有多个可选部分的通用模式的正则表达式,以便我可以确定模式的哪些部分丢失。
这个问题很普遍。第二个点匹配模式抓住了blah
,不必将其返回,(blah)?
因为它是可选的(请参阅此演示,其中我在原始正则表达式中添加了捕获组以显示匹配的组blah
)。
最简单的解决方案是将惰性.*?
模式和(blah)
捕获组封装到一个可选的非捕获组(即(?:.*?(blah))?
)中,以使regex引擎尝试至少一次匹配组模式(=贪婪):
(foo)(?:.*?(blah))?.*?(bar)
请参阅regex演示。在这里,组1中的(foo)
捕获匹配尽可能少的0或多个除换行符以外的其他字符的可选序列,然后捕获到组2中,然后匹配除行中断char之外的0个或多个字符,并尽可能少地匹配然后捕获到第3组:foo
(?:.*?(blah))?
blah
.*?(bar)
bar
另一种解决方案是使用先行限制点匹配(使用所谓的“钢化贪婪令牌”):
(foo)(?:(?!blah).)*(blah)?.*?(bar)
^^^^^^^^^^^^^^
请参阅regex演示。该(?:(?!blah).)*
模式匹配任何文本,直到第一个blah
。(如果它在模式的末尾,则它也可能匹配到字符串的末尾。)
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句