捕获适合正则表达式的所有组

时间:2015-11-17 13:10:58

标签: c# .net regex

我的正则表达式几乎完全符合我的要求:\.?(\w+[\s|,]{1,}\w+[\s|,]{1,}\w+){1}\.?

意思是它捕获连续3个单词的发生率,除了空格和逗号之外没有任何东西(仅限句子的部分)。但是我希望这能匹配句子中每个 3个单词的实例。

所以在这个非常简单的例子中:

Hi this is Bob.

应该有2次捕获 - “嗨,这是”和“这是鲍勃”。我似乎无法弄清楚如何让regex引擎以这种方式解析整个语句。有什么想法吗?

1 个答案:

答案 0 :(得分:2)

您不仅可以在捕获组中获取重叠文本,还可以获取重叠的匹配与捕获您需要的子串的组。

使用

(?=\b(\w+(?:[\s,]+\w+){2})\b)

请参阅regex demo

未锚定的正向前瞻测试在字符串的每个位置处的空字符串匹配。它不消耗字符,但仍然可以返回通过捕获组获得的子匹配。

正则表达式细分:

  • \b - 字边界
  • (\w+(?:[\s,]+\w+){2}) - 以,或空格分隔的3个“单词”。
    • \w+ - 一个或多个字母数字符号,后跟
    • (?:[\s,]+\w+){2} - 包含1个或多个空格或逗号的2个序列,后跟1个或多个字母数字符号。

此模式只是放在前瞻(...)内的捕获组(?=...)中。

单词边界在此表达式中很重要,因为\b会阻止内部匹配(在两个字母数字字符之间)。由于前瞻没有锚定,它会测试输入字符串中的所有位置,而\b可以作为对可以返回匹配位置的限制。

在C#中,您只需收集所有match.Groups[1].Value个,例如像这样:

var s = "Hi this is Bob.";
var results = Regex.Matches(s, @"(?=\b(\w+(?:[\s,]+\w+){2})\b)")
                        .Cast<Match>()
                        .Select(p => p.Groups[1].Value)
                        .ToList();

请参阅IDEONE demo