首页 > 解决方案 > 在 C# 中捕获 const 字符串后的重复模式

问题描述

我需要来自这个字符串的任意数量的版本:

magic-string: [\"1.0.2.2 \", \"1.2\", \"1.1\"];

是)我有的:

[\s""\\]+([\d\.]+)+[\s""\\]+

火柴:

1.0.2.2
1.2
1.1

到目前为止很好,但我想确保“魔法字符串”也可用,这将不匹配:

any-random-string: [\"1.0.2.2 \", \"1.2\", \"1.1\"];

编辑: C# 中的工作解决方案:

public class Program
{
    public static void Main()
    {
        string pattern = @"(?<=^\s*magic-string:\s*\[(?:\s*""(?:\d+(?:\.\d+)*\s*"",)?)+)\d+(?:\.\d+)*";
        var matches = Regex.Matches("        magic-string: [ \"1.0\", \"1.2\", \"1.1\" ];", pattern, RegexOptions.IgnoreCase);

        Console.WriteLine(matches.Count);

        foreach (Match match in matches)
        {
            Console.WriteLine(match.Groups.Count);
            Console.WriteLine(match.Value);
            Console.WriteLine(match.Groups[1].Value);
        }
    }
}

https://dotnetfiddle.net/Kc2J2A

标签: c#regex

解决方案


在支持可变长度后视的语言中(如 .NET 和 JavaScript EMCA2018+):

请参阅此处使用的正则表达式

(?<=^magic-string:\s*\[(?:\s*\\"(?:\d+(?:\.\d+)*\s*\\",)?)+)\d+(?:\.\d+)*

这个怎么运作:

  • (?<=^magic-string:\s*\[(?:\s*\\"(?:\d+(?:\.\d+)*\s*\\",)?)+)积极向后看,确保前面的内容与以下内容匹配
    • ^magic-string:\s*\[和以下相符
      • ^在行首断言位置
      • magic-string:从字面上匹配这个
      • \s*\[匹配任意数量的空白字符,后跟[字面意思
    • (?:\s*\\"(?:\d+(?:\.\d+)*\s*\\",)?)+匹配以下一次或多次
      • \s*\\",匹配任意数量的空白字符,后跟\",字面意思
      • (?:\d+(?:\.\d+)*\s*\\",)?可选匹配以下
      • \d+匹配任何数字一次或多次
      • (?:\.\d+)*然后匹配.一个或多个数字,任意次数(匹配.1,.1.1等,其中1是任意数字)
      • \s*\\"匹配任意数量的空白字符,后跟\"字面意思
  • \d+匹配任何数字一次或多次
  • (?:\.\d+)*然后匹配.一个或多个数字,任意次数(匹配.1,.1.1等,其中1是任意数字)

简单来说,这匹配所有位置0, 0.0, 0.0.0, 等前面magic-string: [\"0.0\", \"的子字符串0.0\", \"出现零次或多次。(0.0作为所有(?:\d+(?:\.\d+)*匹配格式的占位符)。


您可以在支持\G\K标记的语言(如 PCRE)中使用以下正则表达式:

请参阅此处使用的正则表达式

(?:^magic-string:\s*\[|\G(?!\A)\s*\\",)\s*\\"\K\d+(?:\.\d+)*

这个怎么运作:

  • (?:^magic-string:\s*\[|\G(?!\A)\s*\\",)匹配以下任一选项
    • ^magic-string:\s*\[和以下相符
      • ^在行首断言位置
      • magic-string:从字面上匹配这个
      • \s*\[匹配任意数量的空白字符,后跟[字面意思
    • \G(?!\A)\s*\\",和以下相符
      • \G(?!\A)在上一场比赛结束时断言位置
      • \s*\\",匹配任意数量的空白字符,后跟\",字面意思
  • \s*\\"\K\d+(?:\.\d+)*
    • \s*\\"匹配任意数量的空白字符,后跟\"字面意思
    • \K重置匹配的起点,任何先前消耗的字符都不再在最终匹配中
    • \d+匹配任何数字一次或多次
    • (?:\.\d+)*然后匹配.一个或多个数字,任意次数(匹配.1,.1.1等,其中1是任意数字)

简单来说,这匹配前面的所有位置magic-string: [\"或前面匹配的位置后面跟着\", \"


推荐阅读