【问题标题】:How to capture an arbitrary number of groups in JavaScript Regexp?如何在 JavaScript Regexp 中捕获任意数量的组?
【发布时间】:2021-06-24 07:52:33
【问题描述】:

我希望这行 JavaScript:

"foo bar baz".match(/^(\s*\w+)+$/)

返回类似:

["foo bar baz", "foo", " bar", " baz"]

但它只返回最后捕获的匹配项:

["foo bar baz", " baz"]

有没有办法获取所有捕获的匹配项?

【问题讨论】:

    标签: javascript regex repeat capturing-group


    【解决方案1】:

    这个怎么样? "foo bar baz".match(/(\w+)+/g)

    【讨论】:

    • 您的代码有效,但在我的示例中添加全局标志并不能解决问题: "foo bar baz".match(/^(\s*\w+)+$/g) 将返回 ["foo bar baz"]
    • 如果您将其更改为下面的@Jet 正则表达式,它将起作用。 "foo bar baz".match(/\w+/g) //=> ["foo", "bar", "baz"]。它会忽略前面匹配的字符串,但仍然是一个合理的选择。
    【解决方案2】:

    除非您对如何拆分字符串有更复杂的要求,否则您可以拆分它们,然后将初始字符串与它们一起返回:

    var data = "foo bar baz";
    var pieces = data.split(' ');
    pieces.unshift(data);
    

    【讨论】:

    • 这只是我需要的一条建议,让我意识到,至少对于我当前的应用程序,我不需要比 split() 更复杂的东西。跨度>
    【解决方案3】:

    当您重复捕获组时,在大多数情况下,仅保留最后一次捕获;任何先前的捕获都将被覆盖。在某种味道中,例如.NET,您可以获取所有中间捕获,但 Javascript 并非如此。

    也就是说,在 Javascript 中,如果您有一个带有 N 个捕获组的模式,则每次匹配只能准确捕获 N 个字符串,即使其中一些组是重复。

    所以一般来说,取决于你需要做什么:

    • 如果可以选择,请改为使用分隔符拆分
    • 可能匹配/pattern/g,而不是匹配/(pattern)+/,可能在exec 循环中
      • 请注意,这两者并不完全相同,但它可能是一个选项
    • 做多级匹配:
      • 在一场比赛中捕获重复的组
      • 然后运行另一个正则表达式将匹配分开

    参考文献


    示例

    这是一个在文本中匹配 <some;words;here> 的示例,使用 exec 循环,然后在 ; 上拆分以获取单个单词 (see also on ideone.com):

    var text = "a;b;<c;d;e;f>;g;h;i;<no no no>;j;k;<xx;yy;zz>";
    
    var r = /<(\w+(;\w+)*)>/g;
    
    var match;
    while ((match = r.exec(text)) != null) {
      print(match[1].split(";"));
    }
    // c,d,e,f
    // xx,yy,zz
    

    使用的模式是:

          _2__
         /    \
    <(\w+(;\w+)*)>
     \__________/
          1
    

    这匹配&lt;word&gt;&lt;word;another&gt;&lt;word;another;please&gt;等。重复第2组以捕获任意数量的单词,但它只能保留最后一次捕获。整个单词列表由第 1 组捕获;然后这个字符串在分号分隔符上是split

    相关问题

    【讨论】:

      【解决方案4】:

      尝试使用“g”:

      "foo bar baz".match(/\w+/g)
      

      【讨论】:

        【解决方案5】:

        您可以使用 LAZY 评估。 因此,不要使用 * (GREEDY),而是尝试使用 ? (懒惰)

        正则表达式:(\s*\w+)?

        结果:

        第 1 场比赛:foo

        第 2 场比赛:酒吧

        第 3 场比赛:巴兹

        【讨论】:

          猜你喜欢
          • 2012-06-07
          • 1970-01-01
          • 2017-10-13
          相关资源
          最近更新 更多