JS字符串的split()方法是否可以保留分隔符而不移除它们?

76

如何在不删除分隔符的情况下拆分字符串?

假设我有一个字符串: var string = "abcdeabcde";

当我执行 var newstring = string.split("d"),我会得到这样的结果:

["abc","eabc","e"]

但我想得到这个:

["abc","d","eabc","d","e"]

当我尝试编写我的“split2”函数时,我被splice(),索引,“this”与“that”等绕晕了... 帮帮我! :D


@ruffin 这个问题没有被标记,但是有相同的评论指向这里。它们都被建议作为彼此的重复项 - 我们应该想办法决定关闭哪一个 :) - BartoszKP
10个回答

87

尝试:

"abcdeabcde".split(/(d)/);

2
请注意,由于JScript的错误,此代码在IE中无法正常工作。 - bobince
7
OP没有明确指出环境是浏览器还是其他。 - Kai
哪个IE不工作? - CMCDragonkai
3
使用正则表达式 /(?=d)/g - micha
4
这应该是被接受的答案:更简单、更安全,最近很少需要使用 IE。 - Nick McCurdy
显示剩余2条评论

41

我喜欢Kai的回答,但它不完整。相反使用:


"abcdeabcde".split(/(?=d)/g) //-> ["abc", "deabc", "de"]

这是在正则表达式中使用Lookahead Zero-Length Assertion,它可以使匹配结果不包含在捕获组里。无需其他技巧或变通方法。


2
有没有办法得到这个结果://-> ["abcd", "eabcd", "e"] - forresst
@forresst 据我所知,不能使用单个分割命令来实现。但是奇怪的是,接受的答案几乎可以做到这一点,只是在前导定界符而不是尾随定界符上。 - Joachim Lous
5
你可以使用回顾后发现(lookbehind)方法,该方法也在micha提供的链接页面中进行了描述。例如:"abcdeabcde".split(/(?<=d)/g)。 - F Lekschas

35

试试这个:

  1. 将所有的 "d" 实例替换为 ",d"
  2. 以 "," 为分隔符进行拆分
var string = "abcdeabcde";
var newstringreplaced = string.replace(/d/gi, ",d");
var newstring = newstringreplaced.split(",");
return newstring;
希望这能有所帮助。

5
你的解决方案有一个错误——当我用",d,"代替实例而不是",d"时,它才能正常工作。好主意! 因为简单而接受 :) - Martin Janiczek
13
"abcdeabcde".split(/(d)/); - Kai
38
原字符串中有任何逗号 , 都会导致失败。 - bobince
如果您的拆分正则表达式有多个分隔符,您会如何处理?例如 /[abc]/ - dwjohnston
这是错误的答案...你应该像Kai的答案一样使用捕获括号。 - AturSams
显示剩余3条评论

21
var parts= string.split('d');
for (var i= parts.length; i-->1;)
    parts.splice(i, 0, 'd');

(倒序循环是必要的,以避免将 d 添加到已经插入 d 的列表部分。)


+1 比接受的答案更安全。 - alex
12
使用 --> 运算符加一分 :D - Mars Robertson
4
“-->” 运算符的名称是什么? - Oriol
1
这比已接受的答案更好,比正则表达式或替换成可能自然发生的特殊字符更好。 - Benjamin Intal
看到这个答案,我再次很高兴使用 prettier……不过对于功能还是点个赞! - panepeter

5

split - split用于创建分隔行,而不是用于搜索。

[^d] - 查找一组不包含“d”的子字符串

var str = "abcdeabcde";

str.match(/[^d]+|d/g)         // ["abc", "d", "eabc", "d", "e"]
or
str.match(/[^d]+/g)           // ["abc", "eabc", "e"]
or
str.match(/[^d]*/g)           // ["abc", "", "eabc", "", "e", ""]

如果您不想在"javascript"中遇到问题,请阅读"RegExp对象"。


没问题。我尝试让它更清晰易懂。如果我犯了错误,请随意回滚或编辑。 - Conrad Frix
全局对象的更改会影响速度。 方法“RegExp”-多功能且快速。 如果代码很大,理解代码会更容易。 这是我的观点。 - udn79

4
这是我对正则表达式分隔符的版本。它与String.prototype.split具有相同的接口;它将全局和非全局正则表达式视为没有区别。返回值是一个数组,其中奇数成员是匹配的分隔符。
function split(text, regex) {
    var token, index, result = [];
    while (text !== '') {
        regex.lastIndex = 0;
        token = regex.exec(text);
        if (token === null) {
            break;
        }
        index = token.index;
        if (token[0].length === 0) {
            index = 1;
        }
        result.push(text.substr(0, index));
        result.push(token[0]);
        index = index + token[0].length;
        text = text.slice(index);
    }
    result.push(text);
    return result;
}

// Tests
assertEquals(split("abcdeabcde", /d/), ["abc", "d", "eabc", "d", "e"]);
assertEquals(split("abcdeabcde", /d/g), ["abc", "d", "eabc", "d", "e"]);
assertEquals(split("1.2,3...4,5", /[,\.]/), ["1", ".", "2", ",", "3", ".", "", ".", "", ".", "4", ",", "5"]);
assertEquals(split("1.2,3...4,5", /[,\.]+/), ["1", ".", "2", ",", "3", "...", "4", ",", "5"]);
assertEquals(split("1.2,3...4,5", /[,\.]*/), ["1", "", "", ".", "2", "", "", ",", "3", "", "", "...", "4", "", "", ",", "5", "", ""]);
assertEquals(split("1.2,3...4,5", /[,\.]/g), ["1", ".", "2", ",", "3", ".", "", ".", "", ".", "4", ",", "5"]);
assertEquals(split("1.2,3...4,5", /[,\.]+/g), ["1", ".", "2", ",", "3", "...", "4", ",", "5"]);
assertEquals(split("1.2,3...4,5", /[,\.]*/g), ["1", "", "", ".", "2", "", "", ",", "3", "", "", "...", "4", "", "", ",", "5", "", ""]);
assertEquals(split("1.2,3...4,5.", /[,\.]/), ["1", ".", "2", ",", "3", ".", "", ".", "", ".", "4", ",", "5", ".", ""]);
assertEquals(split("1.2,3...4,5.", /[,\.]+/), ["1", ".", "2", ",", "3", "...", "4", ",", "5", ".", ""]);
assertEquals(split("1.2,3...4,5.", /[,\.]*/), ["1", "", "", ".", "2", "", "", ",", "3", "", "", "...", "4", "", "", ",", "5", "", "", ".", ""]);
assertEquals(split("1.2,3...4,5.", /[,\.]/g), ["1", ".", "2", ",", "3", ".", "", ".", "", ".", "4", ",", "5", ".", ""]);
assertEquals(split("1.2,3...4,5.", /[,\.]+/g), ["1", ".", "2", ",", "3", "...", "4", ",", "5", ".", ""]);
assertEquals(split("1.2,3...4,5.", /[,\.]*/g), ["1", "", "", ".", "2", "", "", ",", "3", "", "", "...", "4", "", "", ",", "5", "", "", ".", ""]);

// quick and dirty assert check
function assertEquals(actual, expected) {
  console.log(JSON.stringify(actual) === JSON.stringify(expected));
}

2

试试这个:

var string = "abcdeabcde";
    var delim = "d";
    var newstring = string.split(delim);
    var newArr = [];
    var len=newstring.length;
    for(i=0; i<len;i++)
    {
        newArr.push(newstring[i]);
        if(i != len-1)newArr.push(delim);
    }

0

试试这个

"abcdeabcde".split("d").reduce((result, value, index) => {
    return (index !== 0) ? result.concat(["d", value]) : result.concat(value)
}, [])

0
function split2(original){
   var delimiter = "d", result = [], tmp;
   tmp = original.split(delimiter);
   tmp.forEach(function(x){result.push(x); result.push(delimiter); });
   return result;
}

-1

试试这个

var string = "abcdeabcde";
var res = string.replace( /d/g, 'd\0' ).split(/(?=d)|\0/);
console.log( res );
//["abc", "d", "eabc", "d", "e"]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接