C# 为什么这个表达不遵循贪婪的方法?
为什么这个表达式不遵循贪婪的方法C# 为什么这个表达不遵循贪婪的方法?,c#,regex,regex-greedy,C#,Regex,Regex Greedy,为什么这个表达式不遵循贪婪的方法 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.IgnoreCa
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();
}
string-input=@“酷男人!你的狗可以在水上行走”;
字符串模式=@“酷(?(.*)((((狗)*)(((h)(((.*)))”;
MatchCollection matches=Regex.matches(输入、模式、RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture | RegexOptions.IgnorePatternWhitespace);
foreach(匹配中的匹配)
{
Console.WriteLine(“cool=“+match.Groups[“cool”].Value”);
Console.WriteLine(“dog=“+match.Groups[“dog”]”值);
Console.ReadLine();
}
输出:
酷=人!你的狗能在水上行走
狗=
正如你所观察到的:
(dog)组匹配了0次。但既然,*是贪婪的,为什么它不尝试查找(dog)的最大匹配数,即1
有线索吗?第一个
*
最初匹配整个字符串。然后正则表达式引擎确定是否需要退出以匹配正则表达式的其余部分。但是(?((狗)*)
和(?(h)(?(.*))
都可以合法地匹配零个字符,因此不需要回溯(就*
而言)。尝试在该部分使用非贪婪的*?
编辑(回应下面答案中的附加信息):好的,用非贪婪的*?
替换第一个*
确实有效果,但不是你想要的效果。以前,“酷”一词之后的所有内容都在组中捕获,现在则在组中捕获。下面是正在发生的事情:
匹配单词“cool”后,(?(*?)
最初不匹配任何内容(贪婪行为的反面),而(?((狗)*)
尝试匹配。无论在何处尝试,此部分都将始终成功,因为它可以匹配“dog”或空字符串。这意味着(?(h)…)
中的条件表达式将始终计算为true
,因此它将继续并将其余输入与(?(.*)
匹配
据我所知,您希望匹配命名组
中“cool”之后的所有内容,除非字符串包含单词“dog”;然后,您希望捕获命名组中“dog”之后的所有内容
。您试图使用一个工具来实现这一点,但它并不是真正正确的工具。只要这样做:
cool= man! your dog can walk on water
dog=
string模式=@“酷(?.*?(狗(?.*)?$”;
这里的关键是结尾的
$
;它强制非贪婪的*?
保持匹配,直到到达字符串末尾。因为它是非贪婪的,所以在使用每个字符之前,它会尝试匹配正则表达式的下一部分,(dog(?.*)
。如果单词“dog”在那里,字符串的其余部分将被(?*)
使用;如果没有,正则表达式仍然成功,因为?
使整个部分成为可选的。我曾经尝试过非贪婪(.*?
),但它没有任何效果,因为非贪婪(.*?
代表{0,1}
。因为这里甚至没有匹配的字符,所以没有效果
我的意思是,如果字符串后面有(dog)
,我想捕获该字符串,否则前一组将捕获该字符串(cool(.*)
问题是(dog)
是可选的,如果它存在,我们需要它后面的字符串
使用(dog)?
没有任何效果,因为它再次匹配零个字符
谢谢。我想你对非贪婪量词的看法是错误的;阅读以下内容:其余内容,请参阅我对原始答案的编辑。
string pattern = @"cool (?<cool>.*?) (dog (?<dog>.*))?$";