简而言之,使用标准交替是不可能的。文本匹配后,将无法再次匹配。此外,一旦满足表达式,它就不会继续搜索。如果正则表达式试图匹配所有可能的排列,它们将非常低效,没有人会使用它们。
虽然您的问题没有在文档中明确解决,但我可以找到,它包含在回溯的主题下。请参阅 MSDN 的Backtracking with Optional Quantifiers or Alternation Constructs。
本质上,您的备用列表 ( .|.|.
) 为回溯创造了机会。如果第一个备用不匹配,则将尝试第二个。然而,这种回溯不会发生,除非第一个替代失败,并且一旦匹配,所有其他替代都将被忽略。
如果你想匹配多个表达式,你可以像这样使用前瞻:
string l_pattern = @"(?i)" + /*make the regex case-insensitive*/
@"(?=(?<Cond1>.*?Begin)+)?" +
@"(?=(?<Cond2>.*?Middle)+)?" +
@"(?=(?<Cond3>.*?End)+)?";
string l_input = "Oops - I put the middle first!" +
"Hello this is Begin.This is another begin.";
var l_match = Regex.Match( l_input, l_pattern );
Console.WriteLine( "Cond1 matched {0} times.",
l_match.Groups["Cond1"].Captures.Count );
Console.WriteLine( "Cond2 matched {0} times.",
l_match.Groups["Cond2"].Captures.Count );
Console.WriteLine( "Cond3 matched {0} times.",
l_match.Groups["Cond3"].Captures.Count );
Console.ReadKey( true );
这将输出:
Cond1 匹配 2 次。
Cond2 匹配 1 次。
Cond3 匹配 0 次。
Lookaheads 不捕获任何文本,因此它们的功能类似于正则表达式中的迷你正则表达式。本质上,这个表达式与单独运行所有三个表达式没有什么不同。(请注意,每个前瞻都是可选的,否则如果任何一个前瞻失败,整个表达式都会失败。)
另请注意,当使用我所展示的前瞻时,顺序无关紧要。
有关前瞻的更多信息,请参阅 MSDN 的零宽度正前瞻断言。这个话题有点太大,无法完全解决 SO 答案。
我不能说我会推荐这种方法而不是其他所有方法 - 如果您不熟悉正则表达式并且它不一定是最有效的模式,它可能很难维护,但它符合您的规定要求。