如何在C#Regex中使用lookbehind以跳过重复前缀模式的匹配?
示例 - 我正在尝试让表达式匹配任意数量的b
个字符后的所有a
个字符:
Regex expression = new Regex("(?<=a).*");
foreach (Match result in expression.Matches("aaabbbb"))
MessageBox.Show(result.Value);
返回aabbbb
,后方仅匹配a
。我怎样才能使它与开头的所有a
匹配?
我试过
Regex expression = new Regex("(?<=a+).*");
和
Regex expression = new Regex("(?<=a)+.*");
没有结果......
我期待的是bbbb
。
答案 0 :(得分:7)
您是否正在寻找重复捕获组?
(.)\1*
这将返回两场比赛。
假设:
aaabbbb
这将导致:
aaa
bbbb
此:
(?<=(.))(?!\1).*
使用上面的主体,首先检查找到前一个字符,将其捕获到后一个引用中,然后断言该字符不是下一个字符。
匹配:
bbbb
答案 1 :(得分:4)
我最终弄明白了:
Regex expression = new Regex("(?<=a+)[^a]+");
foreach (Match result in expression.Matches(@"aaabbbb"))
MessageBox.Show(result.Value);
我不能允许a
与我相匹配的非外观组。这样,表达式只会匹配b
次重复后的a
次重复。
匹配aaabbbb
会产生bbbb
并匹配aaabbbbcccbbbbaaaaaabbzzabbb
会产生bbbbcccbbbb
,bbzz
和bbb
。
答案 2 :(得分: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);
}