8

如何在 C# Regex 中使用lookbehind 来跳过重复前缀模式的匹配?

示例 - 我试图让表达式匹配b任意数量字符之后的所有a字符:

Regex expression = new Regex("(?<=a).*");

foreach (Match result in expression.Matches("aaabbbb"))
  MessageBox.Show(result.Value);

返回aabbbb,后向匹配只匹配一个a. 我怎样才能使它a与开头的所有 s 匹配?

我试过了

Regex expression = new Regex("(?<=a+).*");

Regex expression = new Regex("(?<=a)+.*");

没有结果...

我期待的是bbbb

4

3 回答 3

7

您是否在寻找重复捕获组?

(.)\1*

这将返回两个匹配项。

鉴于:

aaabbbb

这将导致:

aaa
bbbb

这:

(?<=(.))(?!\1).*

使用上述原理,首先检查是否找到了前一个字符,将其捕获到反向引用中,然后断言该字符不是下一个字符。

那匹配:

bbbb
于 2010-10-01T13:43:25.637 回答
4

我最终想通了:

Regex expression = new Regex("(?<=a+)[^a]+");

foreach (Match result in expression.Matches(@"aaabbbb"))
   MessageBox.Show(result.Value);

我不能让a我的 s 与非后视组匹配。这样,表达式将只匹配重复之后的那些b重复a

在和中匹配aaabbbb产量bbbb和匹配aaabbbbcccbbbbaaaaaabbzzabbb结果。bbbbcccbbbbbbzzbbb

于 2010-10-01T14:50:42.227 回答
1

后视跳过“a”的原因是因为它正在消耗第一个“a”(但没有捕获它),然后它会捕获其余部分。

这种模式对你有用吗?新模式:\ba+(.+)\b 它使用单词边界\b来锚定单词的两端。它至少匹配一个“a”,然后是其余字符,直到单词边界结束。其余字符被捕获在一个组中,因此您可以轻松引用它们。

string pattern = @"\ba+(.+)\b";

foreach (Match m in Regex.Matches("aaabbbb", pattern))
{
    Console.WriteLine("Match: " + m.Value);
    Console.WriteLine("Group capture: " + m.Groups[1].Value);
}

更新:如果你想跳过任何重复字母的第一次出现,然后匹配字符串的其余部分,你可以这样做:

string pattern = @"\b(.)(\1)*(?<Content>.+)\b";

foreach (Match m in Regex.Matches("aaabbbb", pattern))
{
    Console.WriteLine("Match: " + m.Value);
    Console.WriteLine("Group capture: " + m.Groups["Content"].Value);
}
于 2010-10-01T13:43:02.783 回答