我的任务是将字符串分成两个字符组。
所以'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-学习目的。
答案 0 :(得分:2)
为什么删除$会影响结果?
$
确保字符串的结尾出现在两个字符重复一定次数之后。否则,split
所在的位置将是 any 位置,之后至少有两个字符-这是每个位置的 (仅在结束符之前)字符串)。因此,需要$
才能正确地对字符串进行分块。当某个位置和字符串末尾之间的字符数为奇数时,您希望正则表达式失败,以便(例如)字符0和1被 not 分开,而字符2和3是 not 不分开的,依此类推。
为什么将内部组更改为非捕获组,导致产生不同的结果
当您在split
内使用捕获组时,捕获的任何内容将作为附加项(除字符串的一部分 包含在结果数组中)包含在{ {1}}之前和之后。例如:
split
在这里,字符串在console.log('foobar'.split(/(bar)/));
上分割。没有捕获组,将导致bar
:
['foo', '']
但是由于console.log('foobar'.split(/(?:bar)/));
被捕获,因此将其添加在两者之间。您的
bar
因为最后一个'031745'.split(/(?=(..)$)/);
被捕获了,所以由于它属于捕获组而被包含在结果中,但是由于45
位于 lookahead 中,因此它没有在45
中没有被消耗掉。因此,split
再次包含在结果 中,因为该字符串在45
和0317
之间的位置处被分割了。
45