正则表达式匹配可选组包围任何字符分组

时间:2016-03-24 16:41:12

标签: c# regex

我正在尝试匹配可以在任意数量的字符之前和之后的可选组。整个模式也有一个必需的开始和结束匹配,但中间匹配是可选的。

我从这开始,这在需要中间组时起作用:

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"),但我想知道是否存在纯粹的正则表达式来解决这类问题。我的目标是设计与通用模式匹配的正则表达式,以及多个可选部分,以便我可以确定缺少模式的哪些部分。

2 个答案:

答案 0 :(得分:1)

问题很常见。第二个点匹配模式获取blah并且不必将其返回到(blah)?,因为它是可选的(请参阅this demo我将捕获组添加到原始正则表达式以显示哪个组匹配blah)。

enter image description here

解决方案是使用前瞻限制点匹配(使用所谓的tempered greedy token):

(foo)(?:(?!blah).)*(blah)?.*?(bar)
     ^^^^^^^^^^^^^^

请参阅regex demo(?:(?!blah).)*模式匹配第一个blah之前的任何文本。 (如果它位于模式的末尾,它也可能匹配到字符串的结尾。)

enter image description here

答案 1 :(得分:0)

我能够使用or运算符来处理这两种情况

(foo).*?(blah).*?(bar)|(foo).*?(bar)

Demo