我有以下字符串:
123322
理论上,正则表达式 1.*2
应符合以下条件:
12
(因为*
可以是零字符)12332
123322
如果我使用正则表达式1.*2
,则它与123322
匹配
使用1.*?2
,它将匹配12
。
有没有办法匹配12332
?
完美的事情是在字符串中获得所有可能的matchess (无论一个匹配是另一个的子串)
答案 0 :(得分:2)
不,除非在正则表达式中添加了其他内容以澄清它应该做什么,否则它将是贪婪的或非贪婪的。中间没有;)
答案 1 :(得分:1)
每个案例需要一个单独的表达式,具体取决于您要匹配的两个数量:
1(.*?2){1} #same as 1.*?2
1(.*?2){2}
1(.*?2){3}
...
答案 2 :(得分:1)
通常,这是不可能的。正则表达式匹配引擎并非真正设计用于查找重叠匹配。一个快速的解决方案就是手动检查所有子串的模式:
string text = "1123322";
for (int start = 0; start < text.Length - 1; start++)
{
for (int length = 0; length <= text.Length - start; length++)
{
string subString = text.Substring(start, length);
if (Regex.IsMatch(subString, "^1.*2$"))
Console.WriteLine("{0}-{1}: {2}", start, start + length, subString);
}
}
现在,有可能获得一个完整的正则表达式解决方案吗?大多数情况下,答案是否定的。然而,.Net确实有一些技巧可以帮助我们:它允许可变长度的后视,并允许每个捕获组记住所有捕获(大多数引擎只返回每组的最后一个匹配)。滥用这些,我们可以在正则表达式引擎中模拟相同的for
循环:
string text = "1123322!";
string allMatchesPattern = @"
(?<=^ # Starting at the local end position, look all the way to the back
(
(?=(?<Here>1.*2\G))? # on each position from the start until here (\G),
. # *try* to match our pattern and capture it,
)* # but advance even if you fail to match it.
)
";
MatchCollection matches = Regex.Matches(text, allMatchesPattern,
RegexOptions.ExplicitCapture | RegexOptions.IgnorePatternWhitespace);
foreach (Match endPosition in matches)
{
foreach (Capture startPosition in endPosition.Groups["Here"].Captures)
{
Console.WriteLine("{0}-{1}: {2}", startPosition.Index,
endPosition.Index - 1, startPosition.Value);
}
}
请注意,目前有一个小错误 - 引擎不会尝试匹配最后结束位置($),所以你松了几个匹配。目前,在字符串末尾添加!
可以解决该问题。
答案 3 :(得分:1)