根据ECMA-262 §21.1.3.19 String.prototype.split,
String.prototype.split ( separator, limit )
返回一个Array对象,该对象已存储为将该对象转换为String的结果的子字符串。通过从左到右搜索是否出现分隔符来确定子字符串。 这些事件不是返回数组中任何子字符串的一部分,而是用于划分String值。
但是,我目前正在观察一种奇怪的行为。这是代码:
let s = new String("All the world's a stage, And all the men and women merely players;");
console.log(s.split(/( |o)men /));
预期输出:
[
"All the world's a stage, And all the",
'and w',
'merely players;'
]
实际输出:
[
"All the world's a stage, And all the",
' ',
'and w',
'o',
'merely players;'
]
这是怎么回事?我应该怎么写才能匹配“ men”或“ omen”?
环境:
~ $ node --version
v13.8.0
请注意:
Python3的行为相同。
import re
s = "All the world's a stage, And all the men and women merely players;"
print(re.compile("( |o)men ").split(s))
#=> ["All the world's a stage, And all the", ' ', 'and w', 'o', 'merely players;']
print(re.compile("(?: |o)men ").split(s))
#=> ["All the world's a stage, And all the", 'and w', 'merely players;']
对于这种奇怪的行为(至少对我来说),也许有合理的理由或实际用例...
答案 0 :(得分:4)
String.prototype.split spec也说(在同一段中):
分隔符的值可以是任意长度的字符串,也可以是具有@@ split方法的对象,例如RegExp。
如果我们查看RegExp.prototype [ @@split ]
的规范,它会说:
如果正则表达式包含捕获括号,则每次匹配分隔符时,捕获括号的结果(包括任何未定义的结果)都会被拼接到输出数组中。
这说明了您看到的行为。要解决此问题,只需使用非捕获组即可,即
let s = new String("All the world's a stage, And all the men and women merely players;");
console.log(s.split(/(?: |o)men /));
或者,for better performance,因为您只是交替使用单个字符,所以请使用字符类:
let s = new String("All the world's a stage, And all the men and women merely players;");
console.log(s.split(/[ o]men /));
答案 1 :(得分:2)
找到后,从字符串中删除分隔符,并将子字符串返回到数组中。
如果分隔符是带有捕获括号的正则表达式,则每次分隔符匹配时,捕获括号的结果(包括任何未定义的结果)都会被拼接到输出数组中。