将字符串拆分为数组而不删除分隔符?

我有一个字符串

"asdf ab c2 " 

我想将它拆分成这样的数组:

 ["asdf", " ", "a", " ", " ", "b", " ", "c2", " "] 

使用string.split(" ")删除空格,结果如下:

 ["asdf", "a", "", "b", "c2"] 

我想插入额外的分隔符,例如

 string.replace(/ /g, "| |").replace(/||/g, "|").split("|"); 

但这会产生意想不到的结果。

可能更容易将其视为提取包含分隔符或不是分隔符的连续字符的字符串,而不是拆分:

 'asdf ab c2 '.match(/\S+|\s/g) // result: ["asdf", " ", "a", " ", " ", "b", " ", "c2", " "] 'asdf a b. . c2% * '.match(/\S+|\s/g) // result: ["asdf", " ", "a", " ", " ", "b.", " ", ".", " ", "c2%", " ", "*", " "] 

莎士比亚对比赛的更多定义是:

 'asdf ab c2 '.match(/ |[^ ]+/g) 

或(不是 )+。

使用积极的前瞻:

 "asdf ab c2 ".split(/(?= )/) // => ["asdf", " a", " ", " b", " c2", " "] 

编辑后编辑:正如我在评论中所说,缺乏外观使得这有点棘手。 如果所有单词只包含字母,则可以使用\b字边界匹配器伪造后照:

 "asdf ab c2 ".split(/(?= )|\b/) // => ["asdf", " ", "a", " ", " ", "b", " ", "c2", " "] 

但是一旦你得到一些标点,它就会崩溃,因为它不仅会在空格上打破:

 "asdf-eif.b".split(/(?= )|\b/) // => ["asdf", "-", "eif", ".", "b"] 

如果你确实有非字母,你不想打破,那么我也会建议一个后处理方法。

后想法编辑 :这是基于JamesA的最初想法,但精炼为不使用jQuery,并正确分裂:

 function chop(str) { var result = []; var pastFirst = false; str.split(' ').forEach(function(x) { if (pastFirst) result.push(' '); if (x.length) result.push(x); pastFirst = true; }); return result; } chop("asdf ab c2 ") // => ["asdf", " ", "a", " ", " ", "b", " ", "c2", " "] 

我很惊讶没人提到这个,但为了完整起见,我会在这里发布。 如果在表达式中有捕获组,则.split将捕获的子字符串作为结果数组中的单独条目包含在内:

 "asdf ab c2 ".split(/( )/) // or /(\s)/ // ["asdf", " ", "a", " ", "", " ", "b", " ", "c2", " ", ""] 

请注意,这与您指定的所需输出不完全相同 ,因为它在两个连续空格之间和最后一个空格之后包含一个空字符串。

如有必要,您可以从结果数组中过滤掉所有空字符串,如下所示:

 "asdf ab c2 ".split(/( )/).filter(String) // ["asdf", " ", "a", " ", " ", "b", " ", "c2", " "] 

但是,如果你正在寻找这个,我可能会建议你选择@Jack的解决方案 。

你可以使用一点点jQuery

 var toSplit = "asdf ab c2 ".split(" "); $.each(toSplit, function(index, value) { if (toSplit[index] == '') { toSplit[index] = ' '} } ); 

这将创建您正在寻找的输出,而不会在其他元素上使用前导空格。

 "asdf ab c2 ".split(' ').join(' ,');