.split()。join()返回的字符多于原来的字符数

时间:2014-04-04 02:46:53

标签: javascript regex split

在使用带有捕获组的前瞻分割字符串时,我看到了奇怪的行为。

我有时会获得比原始字符串更多的字符。我认为不可能。

Javascript JsFiddle

'ab'.split(/(?=b)/).join('');
'ab'.split(/(?=(?:b))/).join('');
'ab'.split(/(?=(b))/).join('');

'ab'
'ab'
'abb'

其他语言:

的Java / Scala的

"ab".split("(?=b)").mkString
"ab".split("(?=(?:b))").mkString
"ab".split("(?=(b))").mkString

"ab"
"ab"
"ab"

PHP

implode(preg_split('/(?=b)/', 'ab'));
implode(preg_split('/(?=(?:b))/', 'ab'));
implode(preg_split('/(?=(b))/', 'ab'));

'ab'
'ab'
'ab'

为什么Javascript会出现比第三个正则表达式的原始字符串更多的字符?我已经通过Chrome,Firefox,Opera和IE 11重现了这一点。


修改

看来Ruby做了同样的事情:

'ab'.split(%r{(?=b)}).join
'ab'.split(%r{(?=(?:b))}).join
'ab'.split(%r{(?=(b))}).join

'ab'
'ab'
'abb'

2 个答案:

答案 0 :(得分:4)

来自MDN

  

如果separator是包含捕获括号的正则表达式,则每次匹配separator时,捕获括号的结果(包括任何未定义的结果)都会拼接到输出数组中。

所以,当你有一个捕获组时,即使是在前瞻中,就像这样:

'ab'.split(/(?=(b))/)

结果将包括ab,字符串的两个部分位于与前瞻匹配的位置之前和之后,但它也将包括与内部组匹配的字符串部分前瞻,b

然而,MDN文章接着指出:

  

但是,并非所有浏览器都支持此功能。

所以我不一定希望这种行为在所有浏览器中保持一致。

答案 1 :(得分:0)

这是因为javascript在分割结果中自动捕获组。