我的任务是将一个字符串分成两个字符组。
所以 '031745'
→ [03,17,45]
我采用了正则表达式方法并通过以下方式成功地做到了:
'031745'.split(/(?=(?:..)+$)/);
// result: ["03", "17", "45"]
我知道这里发生了什么:我们正在尝试通过不可见的位置进行拆分,该位置具有后续的 2 个字符组,重复进行。
但是有两件事我觉得很难解释:
1.
如果我删除
end
字符$
,我会得到这个结果:'031745'.split(/(?=(?:..)+)/); // result: ["0", "3", "1", "7", "45"]`
为什么删除
$
会影响结果?毕竟,我们只是在寻找重复的 - 不重叠的两个字符。
2.
为什么将内部组更改为非捕获组,导致产生不同的结果:
'031745'.split(/(?=(..)$)/); // result: ["0317", "45", "45"]
AFAIK - 捕获的组用于反向引用和捕获组。毕竟 - 它仍然是一组重复的两个字符,那么是什么让
(..)
在这种特殊情况下的行为与(?:..)
不同?
nb,我知道还有其他方法,但我仍然想继续使用 Regex - 学习目的。
最佳答案
Why does removing $ affects the result ?
$
确保字符串的结尾出现在两个字符重复一定次数之后。否则,位置 split
on 将是任何 位置,之后至少有两个字符 - 即每个位置(字符串末尾之前除外)。所以,$
需要正确分块字符串。当某个位置和字符串末尾之间有奇数个字符时,您希望正则表达式失败,因此(例如)字符 0 和 1 不分开,而字符 2和 3 不分开,依此类推。
Why does changing the inner group to a non-captured-group , causing to yield a different result
当您在 split
中使用捕获组时,捕获的任何内容都将作为附加项包含在结果数组中,另外到字符串的 split
部分之前和之后。例如:
console.log('foobar'.split(/(bar)/));
在这里,字符串在 bar
处被拆分.如果没有捕获组,它将导致 ['foo', '']
:
console.log('foobar'.split(/(?:bar)/));
但是因为bar
被捕获,它被添加在两者之间。同样的事情发生在你身上
'031745'.split(/(?=(..)$)/);
因为最后45
被捕获,由于在捕获组中,它被包含在结果中,但因为 45
在先行中,它还没有在 split
中消耗掉.所以,45
由于字符串在 0317
之间的位置被拆分,再次 包含在结果中和 45
.
[
"0317", // Initial portion of the string
"45", // Captured group
"45" // Final portion of the string
]
关于javascript - 重复时未捕获的组角色?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52754038/