0

我正在使用 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"].Success 为 false。

4

2 回答 2

1

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

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

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

于 2013-11-13T09:57:33.683 回答
1

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

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

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

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));
        }
    }
}

你可以在这里运行它。

于 2013-11-13T09:58:39.447 回答