7

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

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

它成功匹配了字符串,但突然apple之间peanut就被捕获了。在 C# 和 Perl 中都可以看到这种行为。因此,我假设我错过了一些关于正则表达式匹配如何工作的东西。有任何想法吗?:)

4

4 回答 4

4

给出的值match.Groups[2].Value只是第二组捕获的最后一个值。

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

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

于 2012-11-19T08:41:23.100 回答
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();
于 2012-11-19T08:47:10.093 回答
2

您正在重复您的捕获组,在每次重复匹配时,先前的内容都会被覆盖。因此,最后只有第二个捕获组的最后一场比赛可用。

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

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

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

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

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

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

于 2012-11-19T08:39:53.897 回答
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是一个很好的测试这种东西的网站。

于 2012-11-19T08:49:56.150 回答