在JavaScript中如何一次性拆分字符串?

100

如何仅将字符串拆分一次,即使得1 | Ceci n'est pas une pipe: | Oui解析为:["1","Ceci n'est pas une pipe: | Oui"]

使用split中的limit似乎无法实现...


我不知道2010年的情况如何,但今天大多数使用.split的解决方案比`s.indexOf(...); s.slice(); /* OR: s.substring() */差得多。在Chrome和NodeJS中,“差得多”意味着它们慢了约90%。 - maxkoryukov
17个回答

142
你需要使用String.indexOf('|')来获取第一个'|'出现的位置索引。
var i = s.indexOf('|');
var splits = [s.slice(0,i), s.slice(i+1)];

20
不像Nick的那么"有趣",但可能更有效率。另外请注意,如果分隔符字符串长度超过一个字符,+1实际上应该是分隔符字符串的长度。 - devios1
2
为什么这个解决方案不够有趣呢? - Bentley4
对于那些想知道如何使用2个或更多块来完成此操作的人,您可以在循环中使用indexOf或者: var i = s.split('|',2).join('|').length;//2nd index var splits = [s.slice(0,i).split('|'), s.slice(i+1)]; - Ultimater
8
当IndexOf返回-1时,它不能像split函数一样工作(例如,如果变量s='string',它将返回['strin','string'])。你需要编写一个条件语句。 - JJJ
2
函数看起来不错,但是如果indexOf在字符串s中找不到|字符,它会返回-1,从而导致函数失败。 - aahoogendoorn

88

这并不是一个优美的方法,但效率还不错:

var string = "1|Ceci n'est pas une pipe: | Oui";
var components = string.split('|');
alert([components.shift(), components.join('|')]​);​​​​​

这里有一个快速演示


这比正则表达式更好,我认为。已选择为正确答案,谢谢! - Stavros Korokithakis
2
澄清一下,他将其分成N部分,然后将第一个部分弹出到列表中,并将其余部分连接到同一列表中。 - Stavros Korokithakis
如果您想从字符串中获取k个标记而不是1个,请执行与上述相同的操作,只需使用components.splice(0,k)而不是components.shift()。 - Chiara Coetzee
对于那些想知道如何使用2个或更多块来完成此操作的人,您可以在循环中使用shift或者使用components.splice(0,2).slice(0,2) - Ultimater
1
分割和连接是浪费的。最好使用indexOf解决方案。 - Jonathan

18

ES6语法允许采用不同的方法:

function splitOnce(s, on) {
   [first, ...rest] = s.split(on)
   return [first, rest.length > 0? rest.join(on) : null]
}

如果字符串中没有|,则返回null而不是空字符串,这样更明确。

splitOnce("1|Ceci n'est pas une pipe: | Oui", "|")
>>> ["1", "Ceci n'est pas une pipe: | Oui"]

splitOnce("Celui-ci n'a pas de pipe symbol!", "|")
>>> ["Celui-ci n'a pas de pipe symbol!", null]

没有管道?那就是空的!

我添加了这个回复主要是为了制造一个关于管道符号的双关语,同时展示es6语法 - 多少人仍然不使用它真是太神奇了...


14

您可以使用:

var splits = str.match(/([^|]*)\|(.*)/);
splits.shift();
正则表达式将字符串分成两个匹配组(在括号内),第一个 | 前面的文本和后面的文本。然后,我们使用 shift 函数来去掉整个字符串匹配项(splits[0])。

2
正确地来说,应该在开头加上锚点。然而 JavaScript 的正则表达式似乎很贪婪。 - muhmuhten
这不是杀鸡焉用牛刀吗?使用string.substring()string.indexOf('|')可以以光速完成此操作。 - maxkoryukov

6

一句话总结,我认为更简单:

var str = 'I | am super | cool | yea!';
str.split('|').slice(1).join('|');

这将返回“am super | cool | yea!”

8
这不是被要求的内容,他们也在寻找缺失的前半部分。 - SmujMaiku

4
如果字符串不包含分隔符,@NickCraver的解决方案仍将返回两个元素的数组,第二个元素为空字符串。我更喜欢行为与split相匹配。也就是说,如果输入字符串不包含分隔符,则只返回一个带有单个元素的数组。
var splitOnce = function(str, delim) {
    var components = str.split(delim);
    var result = [components.shift()];
    if(components.length) {
        result.push(components.join(delim));
    }
    return result;
};

splitOnce("a b c d", " "); // ["a", "b c d"]
splitOnce("a", " "); // ["a"]

4

更有效的方法:

const str = "1|Ceci n'est pas une pipe: | Oui"

const [head] = str.split('|', 1);

const result = [head, str.substr(head.length + 1)]

console.log(result);


4

您可以将字符串拆分为数组,然后将第一个元素以外的所有元素连接成一个字符串。

const text = 'a=b=c=d'
const [key, ...values] = text.split('=')
const value = values.join('=')
console.log(key, value)


3

您还可以使用匹配所有内容的正则表达式进行拆分

const str = "one | two | three | four"
const [first, second] = str.split(/\|(.*)/s) // [ 'one ', ' two | three | four', '' ]

我不知道为什么会有一个空字符串,你可以忽略它。只是不要忘记在正则表达式的末尾添加 s(请参见文档),否则它将一直分割到第一个换行符。

3

试试这个:

function splitOnce(input, splitBy) {
    var fullSplit = input.split(splitBy);
    var retVal = [];
    retVal.push( fullSplit.shift() );
    retVal.push( fullSplit.join( splitBy ) );
    return retVal;
}

var whatever = splitOnce("1|Ceci n'est pas une pipe: | Oui", '|');

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