为什么第二个反向引用不起作用?

时间:2019-06-05 14:27:25

标签: javascript regex

我想尽可能多地使用反向引用,以避免重复许多模式的组合。

其他要求:在保持通用性的同时,使用较少的文字而无需构造new RegExp

  

原始标题:为什么捕获组的这种负面前瞻不起作用?

例如,一个字符串:

1.'2.2'.33.'4.4'.5.(…etc)

-我想匹配用句点分隔的字符,并且引号没有分段并且引号被截断。就是这样:

12.2334.45(…etc)

有效的正则表达式为:

(?<=(["'])(?!\.)).*?(?=\1)|((?!["']|\.).)+

console.log(
  "1.'2.2'.33.'4.4'.5.(…etc)".match(
    /(?<=(["'])(?!\.)).*?(?=\1)|((?!["']|\.).)+/g
  )
)

无效的是:

(?<=(["'])(?!\.)).*?(?=\1)|((?!\1|\.).)+
^^

console.log(
  "1.'2.2'.33.'4.4'.5.(…etc)".match(
    /(?<=(["'])(?!\.)).*?(?=\1)|((?!\1|\.).)+/g
  )
)

-它与1335(…etc)不匹配。

为什么( \1 ^^)不起作用,以及如何纠正它?谢谢!

2 个答案:

答案 0 :(得分:2)

主要的困惑似乎是,反向引用不像“ regex子例程”;它们不允许您在其他地方重用部分模式。他们所做的是让您匹配之前再次匹配的确切字符串。

例如:

console.log(/(\w)\1/.test('AB'));
console.log(/(\w)\1/.test('AA'));
console.log(/(\w)\1/.test('BB'));

(\w)\1不匹配AB,但是匹配AABB\1部分仅与之前(\w)组所匹配的字符串完全匹配。

就您而言,

(?<=(["'])(?!\.)).*?(?=\1)
|
((?!\1|\.).)+

有两个用|隔开的分支。第二个分支包含对第一个分支(\1)中捕获组的反向引用((["']))。

这永远不会匹配,因为仅当第一个分支不匹配任何内容时才尝试第二个分支,但是在这种情况下,第一个捕获组也没有匹配任何内容,因此\1指的是什么字符串? / p>

如果反向引用引用的捕获组从不匹配任何内容,则浏览器的行为就像是空字符串一样。

空字符串始终匹配,因此(?!\1)总是失败。

答案 1 :(得分:1)

console.log(
  "1.'2.2'.33.'4.4'.5.(…etc)".match(
    /(["'])[\d.]+\1|\d+/g
  )
)