JavaScript 字符串替换中的子匹配组引用是不是有分隔符/消歧语法?
Posted
技术标签:
【中文标题】JavaScript 字符串替换中的子匹配组引用是不是有分隔符/消歧语法?【英文标题】:Is there a delimiter/disambiguation syntax for submatch group references in JavaScript string replacement?JavaScript 字符串替换中的子匹配组引用是否有分隔符/消歧语法? 【发布时间】:2021-04-29 03:22:25 【问题描述】:这肯定在某个地方已经有了答案,但我什至不知道要搜索什么。
在 javascript 中,我可以在替换字符串中引用带括号的子匹配,如下所示:
"abcdefghijklmnopqrstuvwxyz".replace(/(.)/g, "$1-");
// Result: "a-b-c-d-e-f-g-h-i-j-k-l-m-n-o-p-q-r-s-t-u-v-w-x-y-z-"
现在,我想在每个字母之间添加 1
而不是 -
:
"abcdefghijklmnopqrstuvwxyz".replace(/(.)/g, "$11");
// Result: "a1b1c1d1e1f1g1h1i1j1k1l1m1n1o1p1q1r1s1t1u1v1w1x1y1z1"
至少 Chromium 似乎检测到没有子匹配组 11,因此它将替换字符串解释为“子匹配组 1 后跟 1”。
我们假设有 11 个组:
'abcdefghijklmnopqrstuvwxyz'.replace(/^(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)$/, '$11');
// Result: "k"
我想知道的:
示例 2 是否可以跨浏览器工作?它是否在某个地方定义了它应该表现得像这样? 有没有办法明确界定子匹配组引用?在 bash 中,$a
和 $a
指的是同一个变量,但后者可以将其与以下文本分隔开来。可以让我将示例 3 输出为 "a1"
而不是“k”。
【问题讨论】:
【参考方案1】:JavaScript 正则表达式引擎假定$
之后的最长数字序列是要引用的组 ID,前提是模式中有这样的组,因此如果模式中有一个组,$111
将引用组 111,或者到第 11 组和1
(如果有第 11 组),或者到第 1 组和11
(如果少于 11 个组)。如果根本没有组,它将作为文字字符串返回(即"x".replace(/./g, "$1")
返回$1
)。
console.log('abcdefghijklmnopqrstuvwxyz'.replace(/^(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)$/, '$11')); // => "k"
console.log('abcdefghijklmnopqrstuvwxyz'.replace(/^(.)(.)(.)(.)(.)(.)(.)(.)(.).................$/, '$11')); // => "a1"
如果您知道在您的模式中引用组时可能存在歧义,您可以用零填充组 ID。
$011
将作为对第 1 组和1
的反向引用消除歧义:
console.log('abcdefghijklmnopqrstuvwxyz'.replace(/^(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)$/, '$011')); // => "a1"
不过,你也可以使用named capturing groups with named backreferences:
console.log('abcdefghijklmnopqrstuvwxyz'.replace(/^(?<name>.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)$/, '$<name>1')); // => "a1"
在Table 54: Replacement Text Symbol Substitutions table 中,反向引用语法定义为$n
或$nn
,但是,即使$nnn
语法也是允许的。
Code units | Unicode Characters | Replacement text |
---|---|---|
0x0024, N Where 0x0031 ≤ N ≤ 0x0039 |
$n where n is one of 1 2 3 4 5 6 7 8 9 and $n is not followed by a decimal digit |
The n th element of captures, where n is a single digit in the range 1 to 9 . If n ≤ m and the n th element of captures is undefined, use the empty String instead. If n > m , no replacement is done. |
0x0024, N, N Where 0x0030 ≤ N ≤ 0x0039 |
$nn where n is one of 0 1 2 3 4 5 6 7 8 9
|
The nn th element of captures, where nn is a two-digit decimal number in the range 01 to 99 . If nn ≤ m and the nn th element of captures is undefined, use the empty String instead. If nn is 00 or nn > m , no replacement is done. |
【讨论】:
以上是关于JavaScript 字符串替换中的子匹配组引用是不是有分隔符/消歧语法?的主要内容,如果未能解决你的问题,请参考以下文章