【问题标题】:Regex matching too many groups正则表达式匹配太多组
【发布时间】:2013-11-25 20:11:10
【问题描述】:

我正在使用 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。

【问题讨论】:

  • 您的正则表达式中似乎存在语法错误 - second 前面应该有一个 &lt;。另外,在按索引检索match.Groups 时,您是否检查了组的Success 值?
  • 我已经修正了你注意到的语法(谢谢)。 match.Groups 中的成功值为 {"PO",true;"PO",true;"",false}

标签: c# regex


【解决方案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。

【讨论】:

  • 谢谢,我不知道。
【解决方案2】:

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

"Group 0" 将等于正则表达式所做的全部匹配 (Match.Value)。

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

【讨论】:

    猜你喜欢
    • 2010-11-25
    • 2014-10-06
    • 1970-01-01
    • 2016-12-12
    • 2016-09-08
    • 2012-11-21
    • 2013-08-25
    • 2022-01-21
    • 1970-01-01
    相关资源
    最近更新 更多