正则表达式匹配太多组

时间:2013-11-13 09:35:18

标签: c# regex

我正在使用C#Regex类。我试图从一个分裂两个字符串。源(输入)字符串按以下方式构造:

第一部分必须匹配PO | P | S | [1-5](采用正则表达式语法)。

第二部分可以是VP | GZ | GAR | PP | NAD | TER | NT | OT | LO(再次,正则表达式语法)。第二部分可以发生零次或一次。

可接受的例子是“PO”(一组),“POGAR”(两组PO + GAR),“POT”(P + OT)......

所以我使用了以下正则表达式:

Regex r = new Regex("^(?<first>PO|P|S|[1-5])(?<second>VP|GZ|GAR|PP|NAD|TER|NT|OT|LO)?$");
Match match = r.Match(potentialToken);

当potentialToken为“PO”时,它返回3组!为什么?我只期待一组(第一组)。

match.Groups是{“PO”,“PO”,“”}

命名组正常 - match.Groups [“first”]返回1个实例,而match.Groups [“second”]。成功为假。

2 个答案:

答案 0 :(得分:1)

即使您没有任何捕获组,RegularExpression也始终会在索引0处有一个“Group 0”组。

“组0”将等于正则表达式所做的整个匹配(Match.Value)。

然后在你的情况下你得到3组,因为"Group 0" + "Group first" + "Group second"。如上所述,“第二组”是一个可选组,因此当它不参与主题.Net正则表达式引擎标记"Group second".Success = false时。我在这里看不出任何惊喜。这是预期的行为。

答案 1 :(得分:1)

使用编号的组时,第一个组始终是完整的匹配(子)字符串(参见docs - “Groups属性返回的GroupCollection对象的第一个元素包含一个与整个匹配的字符串正则表达式模式“),即在您的情况下PO

Groups中的第二个元素是第一个命名组的捕获,第三个元素是第二个命名组的捕获 - 就像您可以按名称检索的两个捕获一样。如果您检查编号组的Success,您会看到最后一个元素(与您的第二个命名组匹配的元素)的Success值也为false。您可以将其解释为“该组存在,但它与任何内容都不匹配”。

要确认这一点,请查看此测试代码的输出:

using System;
using System.Text.RegularExpressions;

class Program
{
    static void Main()
    {
        Regex r = new Regex("^(?<first>PO|P|S|[1-5])(?<second>VP|GZ|GAR|PP|NAD|TER|NT|OT|LO)?$");
        Match match = r.Match("PO");

        for (int i = 0; i < match.Groups.Count; i++) {
            Console.WriteLine(string.Format("{0}: {1}; {2}", i, match.Groups[i].Success, match.Groups[i].Value));
        }
    }
}

您可以运行here