我正在尝试匹配一个可选组,该组前面和后面可以有任意数量的字符。整个模式也有必需的开始和结束匹配,但中间的匹配是可选的。
我从这个开始,当需要中间组时它有效:
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”。
This 所以答案 https://stackoverflow.com/questions/31772440/regex-force-parsing-optional-groups说如果可选组之前和之后有分隔符,我可以捕获中间可选组,但这不是我的情况。
我可以完全跳过可选组并使用string.Contains("blah")
,但我想知道是否有一个纯粹的正则表达式解决此类问题。我的目标是设计与通用模式匹配的正则表达式,具有多个可选部分,以便我可以确定模式的哪些部分丢失。
这个问题很常见。第二个点匹配模式抓住了blah
并且不必将其交还给(blah)?
因为它是可选的(参见我将捕获组添加到原始正则表达式中以显示哪些组匹配blah
).
最简单的解决方案是封闭惰性.*?
模式和(blah)
将捕获组转换为可选的非捕获组(即(?:.*?(blah))?
)使正则表达式引擎尝试匹配组模式至少一次(=greedily):
(foo)(?:.*?(blah))?.*?(bar)
See the . Here, (foo)
捕获foo
在第 1 组中,(?:.*?(blah))?
匹配除换行符之外的 0 个或更多字符的可选序列,尽可能少,然后捕获blah
进入第2组,然后.*?(bar)
匹配0个或多个除换行符之外的字符,尽可能少,然后捕获bar
进入第 3 组:
另一种解决方案是通过前瞻来限制点匹配(使用所谓的脾气暴躁的贪婪令牌 http://www.rexegg.com/regex-quantifiers.html#tempered_greed):
(foo)(?:(?!blah).)*(blah)?.*?(bar)
^^^^^^^^^^^^^^
See the . The (?:(?!blah).)*
模式匹配第一个之前的任何文本blah
。 (如果它位于模式的末尾,它也可能匹配到字符串的末尾。)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)