【问题标题】:Regular expression to match optional group匹配可选组的正则表达式
【发布时间】:2018-07-14 21:38:37
【问题描述】:

我期待一个字符串,它可能有也可能没有'#',后跟一些数字。如果“#”之后有任何数字,我想将其捕获为第二组,否则只需捕获第一组中的所有内容。以下是 C# 的示例

  • ABC#99999//匹配Group1:ABC和Group2:99999
  • 9ABC#8 //匹配 Group1 9ABC 和 Group
  • 9ABC //匹配 Group1 9ABC
  • 9ABC# //匹配 Group1 9ABC#

以下正则表达式有效,但对于第 3 和第 4 个字符串,它捕获到第 3 组而不是第 1 组。对于上述情况,是否有更好的方法?

(?:(.+)#(\d+))|(.+)

另外,我想出了以下正则表达式,但问题是由于第一组没有固定格式(如长度),它从第一个和第二个字符串中捕获整个字符串,而不是捕获 2 个组

(.+)(?:#(\d+))?

【问题讨论】:

  • 那么,你基本上想匹配整个字符串,对吧?
  • @WiktorStribiżew 是的,但如果 '#' 之后有数字,我需要将它们捕获到两个单独的组中
  • 好的,然后见my answer below。请修正问题中的预期结果,因为要求与示例不同步。
  • @Praati 我根据您对“CertainPerformance”答案的评论编辑了第 4 个示例输出,对吗?

标签: c# .net regex


【解决方案1】:

要匹配整个字符串并将可选的# + 数字之前的部分放入第 1 组,并将所有这些数字放入第 2 组,您可以使用

^(.+?)(?:#(\d+))?$

请参阅.NET regex demo。添加 \r? 是因为它是一个多行输入演示,如果您打算针对该模式测试单独的字符串,则不需要它。

详情

  • ^ - 字符串开头
  • (.+?) - 第 1 组:尽可能少的一个或多个字符(由于 +? 惰性量词)(注意,如果第 1 组值可能丢失,请改用 (.*?))李>
  • (?:#(\d+))? - 一个可选的非捕获组,匹配 1 次或 0 次出现
    • # - # 符号
    • (\d+) - 第 2 组:一位或多位数字
  • $ - 字符串结束。

【讨论】:

  • 我想你回答了我的问题。我将对其进行测试并将其标记为已回答。谢谢
【解决方案2】:

试试

(\w+)(?:#(\d+))?

# 位于可选的非捕获组中,而捕获组中的以下数字非捕获组中。

https://regex101.com/r/obKPFw/1

【讨论】:

  • 这行得通,但很抱歉,我需要在第四个示例中捕获 9ABC#。我的问题打错了,对此我深表歉意。
  • @Praati 请在问题中修复它,因为要求与示例不同步。
  • 真是愚蠢的问题,我该如何编辑我的问题。我去了我的个人资料>问题...没有看到编辑按钮
  • @Praati 这是问题本身下方的按钮,就在标签下方。
【解决方案3】:

另一种解决方案,不使用正则表达式:

public class Program
{
    static void Main(string[] args)
    {
        List<string> inputs = new List<string>
        {
            "ABC#99999",
            "9ABC#8",
            "9ABC",
            "9ABC#"
        };

        var groups = new List<Group>();

        foreach (string input in inputs)
        {
            string[] parts = input.Split("#", StringSplitOptions.RemoveEmptyEntries);

            var group = new Group
            {
                Part1 = input
            };
            
            if (parts.Length == 2)
            {
                group.Part1 = parts[0];
                group.Part2 = parts[1];
            };

            groups.Add(group);

            Console.WriteLine($"Input: '{input}': {group}");
        }

        Console.ReadKey();
    }
}

public class Group
{
    public string Part1 { get; set; }
    public string Part2 { get; set; }

    /// <inheritdoc />
    public override string ToString()
    {
        return $"Part1: {Part1 ?? "null"}, Part2: {Part2 ?? "[null]"}";
    }
}

输出:

输入:'ABC#99999':Part1:ABC,Part2:99999

输入:'9ABC#8':Part1:9ABC,Part2:8

输入:'9ABC':Part1:9ABC,Part2:[null]

输入:'9ABC#':Part1:9ABC#,Part2:[null]

【讨论】:

    猜你喜欢
    • 2020-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-02
    • 1970-01-01
    • 2016-06-06
    相关资源
    最近更新 更多