奇数正则表达式行为 - 仅匹配第一个和最后一个捕获组

时间:2012-11-19 08:32:28

标签: c# regex perl capture

我正在尝试编写一个与逗号分隔的单词列表匹配并捕获所有单词的正则表达式。此行应与   apple , banana ,orange,peanut 匹配,并且捕获应为applebananaorangepeanut。为此,我使用以下正则表达式:

^\s*([a-z_]\w*)(?:\s*,\s*([a-z_]\w*))*\s*$

它成功匹配字符串,但突然只捕获applepeanut。在C#和Perl中都可以看到这种行为。因此,我假设我遗漏了有关正则表达式匹配如何工作的事情。有任何想法吗? :)

4 个答案:

答案 0 :(得分:4)

match.Groups[2].Value给出的值只是第二组捕获的 last 值。

要查找所有值,请查看match.Groups[2].Captures[i].Value,在这种情况下,i的范围从02。 (以及第一组的match.Groups[1].Value。)

(问题为+ 1,我今天学到了一些东西!)

答案 1 :(得分:3)

试试这个:

string text = "   apple , banana ,orange,peanut";

var matches = Regex.Matches(text, @"\s*(?<word>\w+)\s*,?")
        .Cast<Match>()
        .Select(x => x.Groups["word"].Value)
        .ToList();

答案 2 :(得分:2)

您是repeating your capturing group,在每次重复比赛时,之前的内容都会被覆盖。因此,最后只有第二个捕获组的最后一个匹配。

您可以将第二个捕获组更改为

^\s*([a-z_]\w*)((?:\s*,\s*(?:[a-z_]\w*))*)\s*$

然后结果将是你的第二组中的“香蕉,橙子,花生”。我不确定,如果你想要这个。

如果要检查字符串是否具有该模式并提取每个单词。我会分两步完成。

  1. 使用正则表达式检查模式。

  2. 如果模式正确,请删除前导和尾随空格并在\s*,\s*上拆分。

答案 3 :(得分:2)

简单的正则表达式:

(?:^| *)(.+?)(?:,|$)

说明:

?:    # Non capturing group
^| *  # Match start of line or multiple spaces
.+    # Capture the word in the list, lazy
?:    # Non capture group
,|$   # Match comma or end of line 

注意:Rublular是一个很好的网站,用于测试此类事情。