【问题标题】:Why this expression not following greedy approach?为什么这个表达式不遵循贪婪的方法?
【发布时间】:2010-12-30 02:31:04
【问题描述】:

为什么这个表达式不遵循贪婪的方法?

string input = @"cool  man! your  dog can walk on water ";
string pattern = @"cool (?<cool>(.*))    (?<h>((dog)*)) (?(h)(?<dog>(.*))) ";

MatchCollection matches = Regex.Matches(input, pattern, RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture | RegexOptions.IgnorePatternWhitespace);


foreach (Match match in matches)
{
    Console.WriteLine("cool=" + match.Groups["cool"].Value);
    Console.WriteLine("dog=" + match.Groups["dog"].Value);
    Console.ReadLine();
}

输出:

酷=男人!你的狗可以在水上行走 狗=

如您所见: (dog) 组匹配 0 次。但是,* 是贪婪的,为什么不尝试找到 (dog) 的最大匹配为 1?

有什么线索吗?

【问题讨论】:

    标签: c# regex regex-greedy


    【解决方案1】:

    第一个 .* 最初匹配整个字符串。然后正则表达式引擎确定是否需要回退以匹配正则表达式的其余部分。但是(?&lt;h&gt;((dog)*))(?(h)(?&lt;dog&gt;(.*))) 都可以合法地匹配零个字符,因此不需要回溯(就.* 而言)。尝试在该部分使用非贪婪的.*?

    编辑(响应下面答案中发布的附加信息):好的,用非贪婪的.*? 替换第一个 .* 确实一种效果,只是不是你想要的那种。之前“酷”一词之后的所有内容都在&lt;cool&gt; 组中被捕获,现在它在&lt;dog&gt; 组中被捕获。以下是正在发生的事情:

    匹配“cool”一词后,(?&lt;cool&gt;(.*?)) 最初不匹配(与贪婪行为相反),(?&lt;h&gt;((dog)*)) 尝试匹配。这部分总是会成功,无论在哪里尝试,因为它可以匹配“dog”或空字符串。这意味着(?(h)...) 中的条件表达式将始终计算为true,因此它会继续并将输入的其余部分与(?&lt;dog&gt;(.*)) 匹配。

    据我了解,您希望匹配命名组&lt;cool&gt; 中“cool”之后的所有内容,除非字符串包含单词“dog”;那么你想在命名组&lt;dog&gt; 中捕获“狗”之后的所有内容。您正在尝试为此使用conditional,但这并不是真正正确的工具。只需这样做:

    string pattern = @"cool (?<cool>.*?) (dog (?<dog>.*))?$";
    

    这里的关键是末尾的$;它强制非贪婪的.*? 继续匹配,直到它到达字符串的末尾。因为它是非贪婪的,所以它会在使用每个字符之前尝试匹配正则表达式的下一部分 (dog (?&lt;dog&gt;.*))。如果存在单词“dog”,则字符串的其余部分将被(?&lt;dog&gt;.*) 消耗;如果没有,正则表达式仍然会成功,因为 ? 使整个部分成为可选的。

    【讨论】:

      【解决方案2】:

      我确实尝试过非贪婪的(.*?),但它没有效果,这很明显,因为非贪婪的(.*?) 代表{0,1}。因为即使是零个字符也匹配这里,所以没有效果。

      任何想法如何纠正它。我的意思是,我想捕获后面跟有(dog) 的字符串(如果它存在的话),否则前一组将捕获字符串(cool(.*))

      问题是(dog) 是可选的,如果它存在,我们需要它后面的字符串。

      使用(dog)? 没有任何效果,因为它再次匹配零个字符。

      谢谢。

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-09-01
      • 2020-03-12
      • 1970-01-01
      • 1970-01-01
      • 2011-01-17
      • 2019-12-23
      • 2012-04-27
      相关资源
      最近更新 更多