Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Regex 正则表达式行为懒惰,应该是贪婪的_Regex_Greedy_Non Greedy_Regex Greedy_Alternation - Fatal编程技术网

Regex 正则表达式行为懒惰,应该是贪婪的

Regex 正则表达式行为懒惰,应该是贪婪的,regex,greedy,non-greedy,regex-greedy,alternation,Regex,Greedy,Non Greedy,Regex Greedy,Alternation,我认为默认情况下,我的Regex会表现出我想要的贪婪行为,但它不在以下代码中: 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("Ma

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

 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
现在我意识到,如果我简单地按长度降序对关键字进行排序,我就可以在这个小示例中使用它,但是

  • 我想知道为什么会这样 没有按预期工作,并且
  • 我正在从事的实际项目 在正则表达式和 重要的是要把他们留在家里 按字母顺序排列

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

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

根据,正则表达式是。因此,当它通过你的,它停止在第一个坚实的比赛


我的建议是将所有关键字存储在数组或列表中,然后在需要时生成经过排序的管道表达式。只要你的关键字列表没有改变,你就只需要做一次。只需将生成的表达式存储在某种类型的单例中,并在正则表达式执行时返回该表达式。

看起来您正在尝试用词来破坏东西。要做到这一点,需要整个表达式是正确的,而当前表达式不是。试试这个

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

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

除了重新排序之外,没有其他选项?嗯…我想我可以在飞行中重新排序,这样我就可以按照字母顺序来定义…@Stomp:可以。在程序中保持列表按字母顺序排列,在实际应用之前,可以按长度排序。@Jeras-谢谢链接!我在MSDN上搜索,肯定错过了它急切地寻找第一个匹配项。我不确定您的实际使用是否更复杂,但如果上面的示例是您正在做的,我认为您最好使用IndexOf方法在您的单词列表上循环查找匹配项。如果正则表达式只是在一个替换中包含一堆单词,那么性能可能会很差。@Josh-No,这个例子被简化了。实际的应用程序正在读取语言文件以生成词法分析器和语法分析器。我只是对我的正则表达式有点生疏;我的问题现在看来很明显@Josh:Regex引擎可以对这种情况进行很多优化,包括在未能匹配公共前缀后放弃许多检查。例如,如果第一个字符不是“i”,则不会检查以“i”开头的分支。不确定.NET引擎是否会这样做,但如果它没有这样做,我会感到惊讶。@Max,它确实会构建状态转换以加快匹配速度。从我收集的资料来看,如果.Net与其他久负盛名、精益求精的regex引擎相比,是否表现出色,这是一个有争议的问题。但它确实比IndexOf表现更好。(我已经在工作中运行了这两个循环来证明为什么同事应该使用regex而不是IndexOf…根据匹配的内容,您可以获得大幅度的速度提升。)添加
\b
将获得所需的行为,但您对其工作方式的理解是错误的
\b
是一个零宽度断言,类似于
^
$
和lookarounds;它不匹配字符,而是匹配字符前后的假想间隙。如果第一个或最后一个字符(分别)是单词字符,字符串的开头或结尾将自动成为单词边界,因此您的第二个正则表达式只是第一个正则表达式的更详细版本。@Alan,我尝试过执行代码,显然您是对的。我需要再次检查工作中的代码,看看我们在那里做什么。。。也许我们使用的是\W而不是\b。我知道我们在类似的情况下得到了某种“非文字”角色,我知道我们有一些时髦的午间抓拍组。至于它是区域敏感的,这将是一种情况,因为单词边界将根据标点符号的作用进行不同的定义。@Alan,我修改了我的答案以反映您的反馈。