[英]Regex Match Optional Group Surrounded by Any Character Grouping
我正在尝试匹配一个可选组,该组可以在任意数量的字符之前和之后。 整个模式也有一个必需的开始和结束匹配,但中间匹配是可选的。
我从这个开始,它在需要中间组时起作用:
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”。
这个SO answer说如果在可选组之前和之后有分隔符,我可以捕获中间的可选组,但这不是我的情况。
我可以完全跳过可选组并使用string.Contains("blah")
,但我想知道是否有针对此类问题的纯正则表达式解决方案。 我的目标是设计与通用模式匹配的正则表达式,具有多个可选部分,以便我可以确定缺少模式的哪些部分。
这个问题很常见。 第二个点匹配模式抓住了blah
并且不必将其归还给(blah)?
因为它是可选的(请参阅此演示,其中我将捕获组添加到原始正则表达式以显示哪些组匹配blah
)。
最简单的解决方案是将惰性.*?
模式和(blah)
捕获组到一个可选的非捕获组(即(?:.*?(blah))?
)以使正则表达式引擎尝试匹配组模式至少一次(= greedily ):
(foo)(?:.*?(blah))?.*?(bar)
请参阅正则表达式演示。 这里, (foo)
捕获了 Group 1 中的foo
, (?:.*?(blah))?
匹配 0 个或更多字符的可选序列,除换行符之外,尽可能少,然后将blah
捕获到组 2 中,然后.*?(bar)
匹配 0 个或更多除换行符以外的字符,尽可能少然后将bar
捕获到组 3 中:
另一种解决方案是使用前瞻来限制点匹配(使用所谓的缓和贪婪令牌):
(foo)(?:(?!blah).)*(blah)?.*?(bar)
^^^^^^^^^^^^^^
请参阅正则表达式演示。 (?:(?!blah).)*
模式匹配直到第一个blah
任何文本。 (如果它在模式的末尾,它也可能匹配到字符串的末尾。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.