11

我认为默认情况下我的正则表达式会表现出我想要的贪婪行为,但它不在以下代码中:

 Regex keywords = new Regex(@"in|int|into|internal|interface");
 var targets = keywords.ToString().Split('|');
 foreach (string t in targets)
    {
    Match match = keywords.Match(t);
    Console.WriteLine("Matched {0,-9} with {1}", t, match.Value);
    }

输出:

Matched in        with in
Matched int       with in
Matched into      with in
Matched internal  with in
Matched interface with in

现在我意识到,如果我只是按长度降序对关键字进行排序,我可以让它适用于这个小例子,但是

  • 我想了解为什么这不能按预期工作,并且
  • 我正在处理的实际项目在正则表达式中有更多的单词,并且保持它们按字母顺序排列很重要。

所以我的问题是:为什么这是懒惰的,我该如何解决?

4

3 回答 3

12

懒惰和贪婪仅适用于量词(?, *, +, {min,max})。交替总是按顺序匹配并尝试第一个可能的匹配。

于 2010-03-07T02:29:24.417 回答
6

看起来你正试图用言语破坏事物。为此,您需要整个表达式正确,而您当前的表达式不是。试试这个吧。。

new Regex(@"\b(in|int|into|internal|interface)\b");

"\b" 表示匹配单词边界,并且是零宽度匹配。这是依赖于语言环境的行为,但通常这意味着空格和标点符号。作为零宽度匹配,它将不包含导致正则表达式引擎检测单词边界的字符。

于 2010-03-07T03:28:05.173 回答
3

根据RegularExpressions.info,正则表达式是急切的。因此,当它通过您的管道表达式时,它会在第一个实体匹配时停止。

我的建议是将所有关键字存储在一个数组或列表中,然后在需要时生成已排序的管道表达式。只要您的关键字列表不变,您只需执行一次。只需将生成的表达式存储在某种单例中,然后在正则表达式执行时返回。

于 2010-03-07T02:37:48.050 回答