0

我有一个带有 OR 条件的正则表达式。我想从由“|”分隔的正则表达式中存在的所有条件中找出满足的条件数。

例子 :(.*Begin.*)|(.*Middle.*)|(.*End.*)

我也有一个字符串,如:"Hello this is Begin.Hello this is Middle."

现在,如果您在正则表达式中看到 3 个或条件中的 2 个,则会在此规则中命中。我想找到命中的条件数。

我不想根据' |'拆分正则表达式,然后单独应用每个。我想一次运行整个正则表达式。

在我们正在搜索的字符串中,子匹配的顺序并不总是 Begin-->Middle-->End。这是一个完全随机的字符串,我们在其中应用包含条件的正则表达式组合成一个正则表达式。我想知道 Regex 中的这些条件中有多少受到了影响。

4

4 回答 4

2

简而言之,使用标准交替是不可能的。文本匹配后,将无法再次匹配。此外,一旦满足表达式,它就不会继续搜索。如果正则表达式试图匹配所有可能的排列,它们将非常低效,没有人会使用它们。

虽然您的问题没有在文档中明确解决,但我可以找到,它包含在回溯的主题下。请参阅 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 答案。

我不能说我会推荐这种方法而不是其他所有方法 - 如果您不熟悉正则表达式并且它不一定是最有效的模式,它可能很难维护,但它符合您的规定要求。

于 2013-05-22T17:12:27.670 回答
0

使用此模式:

(.*Begin|Middle|End.*)

并找到 RegEx 引擎返回的匹配数。

这样的事情会帮助你:

MatchCollection mcoll = Regex.Matches("sample string to match","(.*Begin|Middle|End.*)")
int count = mcoll.Count

此外,如果您希望对此模式进行不区分大小写的匹配前缀,(?i)则该模式将如下所示:

(?i)(.*Begin|Middle|End.*)

希望能帮助到你!

于 2013-05-22T16:52:23.800 回答
0
Regex regexObj = new Regex("Begin|Middle|End");
allMatchResults = regexObj.Matches(subjectString);
numberOfMatches = allMatchResults.Count
于 2013-05-20T11:27:26.900 回答
0

如果正则表达式片段匹配互斥的语言集(或者较弱但更难验证的条件是它们匹配输入字符串中的非重叠子字符串),那么您可以找到所有匹配项并计算构成匹配项的捕获组的数量在字符串中。

如果正则表达式片段匹配重叠的子字符串,那么最简单的方法是尝试将每个正则表达式片段与字符串匹配并计数。

于 2013-05-20T11:28:03.500 回答