【问题标题】:Javascript match regex behaviour [duplicate]Javascript匹配正则表达式行为[重复]
【发布时间】:2020-01-17 13:10:58
【问题描述】:

我正在学习 Javascript 中的匹配运算符、捕获组等。但我很难理解以下内容的工作原理。

var string = 'string of random words';
var match = string.match(/((random)|(words))/);
// returns array of 4 elements
0: "random"
1: "random"
2: "random"
3: undefined

我正在努力解决这个问题。我可以看到有一个管道字符,这意味着匹配字符串“随机”或“单词”。我可以看到 random 和单词在括号中,所以这是一个捕获组,整个表达式周围都有括号。

有人可以帮忙吗?

var string = 'string of random words';
var match = string.match(/((random)|(words))/);
console.log(match)

【问题讨论】:

标签: javascript regex match


【解决方案1】:

RegExp 匹配数组的第一个 ([0]th) 元素是整个匹配项。

不以(?: 开头的括号( 表示捕获组。 ((?:表示非捕获组)

第二个 ([1]) 元素是第一个捕获组。如果组根本不匹配(例如,'foo'.match('(z)|(f)')),它将包含undefined

匹配数组的其他索引的行为方式相同 - [2] 元素对应于第二个捕获组,[3]rd 元素对应于第三个捕获组,依此类推。

匹配数组将包含等于表达式中捕获组数加一的元素(对于位置 0 处的完全匹配)。

这里发生了什么:

  • 完全匹配是random
  • 第一个捕获组包含整个匹配 - 与完整匹配相同,random
  • 第二个捕获组,在第一个捕获组内,但恰好也消耗了所有字符:random
  • 第三个捕获组,在第一个捕获组内:不匹配(因为当正则表达式仅匹配左侧时,它位于| 的右侧):包含undefined
/((random)|(words))/
  ^^^^^^^^^^^^^^^^^ First capture group (matched, contains "random")
/((random)|(words))/
   ^^^^^^           Second capture group (matched, contains "random")
/((random)|(words))/
            ^^^^^ Third capture group (not matched this time, so undefined)

如果您是 regex 匹配数组的新手,通过查看当组不都包含相同文本时会发生什么情况会更容易理解:

var string = 'abcdef';
var match = string.match(/ab(c(de)|(zzz))/);
console.log(match)
ab(c(de)|(zzz))
^^^^^^^^^^^^^^^ Full match (abcde)
ab(c(de)|(zzz))
   ^^^^^^^^^^^ First capture group (cde)
ab(c(de)|(zzz))
     ^^        Second capture group (de)
ab(c(de)|(zzz))
          ^^^  Third capture group (not matched, so undefined)

【讨论】:

    【解决方案2】:

    您不匹配words,因为您的正则表达式缺少全局标志g。此标志告诉正则表达式在第一次匹配后不要停止。如果您将此标志添加到您的正则表达式,您将匹配随机和单词。

    var string = 'string of random words';
    var match = string.match(/((random)|(words))/g);
    console.log(match)

    这里对您的正则表达式的作用进行了更深入的解释。

    如果你每个人都在使用正则表达式,我建议使用像regex101 这样的网站,它确实有助于正确理解。

    【讨论】:

      【解决方案3】:
      1. 第一个条目:在/ /指定匹配的对象之间,要求为randomwords,可以匹配为random
      2. 第二个条目: 第一个开口( 到匹配的),匹配是random
      3. 第三次进入:第二次开启(到匹配),匹配 是random
      4. 第四条:第三条开启(到匹配 ),没有任何匹配项。

      为什么第四个条目不匹配?因为它试图在字符串中获取满足您“随机或单词”要求的一段内容,并且在randomr 处,可以匹配random 的正则表达式部分,但words 不能,所以第三个捕获组是未定义的。

      如果你指定the g flag or modifier

      如果使用了g标志,所有结果匹配完整的正则表达式将被返回,但捕获组不会。

      console.log('string of random words'.match(/((random)|(words))/g));

      它是这样的:从strings开始,它可以匹配你的“随机或单词”的正则表达式吗?这不可以。然后向右移动1个字符,它可以匹配“随机或单词”吗?不,……等等。在randomr 处,它可以匹配你的正则表达式,然后在random 之后的空格处,它可以匹配你的正则表达式吗?不。右边的一个字符,它可以……等等。这就是为什么“所有结果”都是["random", "words"]

      因此您可以一次又一次地继续扫描所有匹配项,但缺点是您无法访问捕获组。

      如果你想要to be able to scan all the matches, but also want the capture groups? Then you can use matchAll():

      console.log([...'string of random words'.matchAll(/((random)|(words))/g)]);

      您可以看到,在wordsw 处,它与您的正则表达式的words 部分匹配,而random 的第二个捕获组不匹配。

      【讨论】:

        猜你喜欢
        • 2015-05-07
        • 1970-01-01
        • 1970-01-01
        • 2016-03-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多