String einmal in Javascript teilen?

81

Wie kann ich einen String nur einmal teilen, dh 1|Ceci n'est pas une pipe: | Ouianalysieren : ["1", "Ceci n'est pas une pipe: | Oui"].

Das Limit bei der Aufteilung scheint nicht zu helfen ...

Stavros Korokithakis
quelle

Antworten:

77

Dies ist kein schöner Ansatz, funktioniert aber mit anständiger Effizienz:

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

Hier ist eine kurze Demo davon

Nick Craver
quelle
Das ist eigentlich besser als der reguläre Ausdruck, denke ich. Als richtig ausgewählt, danke!
Stavros Korokithakis
2
Zur Verdeutlichung teilt er sich in N Teile auf, fügt dann den ersten Teil einer Liste hinzu und fügt den Rest derselben Liste hinzu.
Stavros Korokithakis
Wenn Sie k Token anstelle von 1 von der Zeichenfolge entfernen möchten, gehen Sie wie oben beschrieben vor, verwenden Sie jedoch components.splice (0, k) anstelle von components.shift ().
D Coetzee
Für diejenigen, die sich fragen, wie man das mit 2 oder mehr Spannfuttern macht, können Sie Shift in einer Schleife verwenden oder:components.splice(0,2).slice(0,2)
Ultimater
113

Sie möchten verwenden String.indexOf('|'), um den Index des ersten Auftretens von '|' abzurufen.

var i = s.indexOf('|');
var splits = [s.slice(0,i), s.slice(i+1)];
Yarmiganosca
quelle
17
Nicht so "lustig" wie Nicks, aber wahrscheinlich effizienter. Beachten Sie auch, +1dass dies eigentlich die Länge der Trennzeichenfolge sein sollte, wenn mehr als ein Zeichen vorhanden ist.
Devios1
Warum macht diese Lösung weniger "Spaß"?
Bentley4
Für diejenigen, die sich fragen, um dies mit 2 oder mehr Blöcken zu tun, könnten Sie indexOf in einer Schleife verwenden oder:var i = s.split('|',2).join('|').length;//2nd index var splits = [s.slice(0,i).split('|'), s.slice(i+1)];
Ultimater
6
Dies funktioniert NICHT wie split, wenn IndexOf -1 zurückgibt (z. B. wenn var s = 'string' ['strin', 'string'] zurückgibt). Sie müssten eine Bedingung schreiben.
JJJ
14

Sie können verwenden:

var splits = str.match(/([^|]*)\|(.*)/);
splits.shift();

Der reguläre Ausdruck teilt die Zeichenfolge in zwei übereinstimmende Gruppen (in Klammern) auf, wobei der Text vor dem ersten | steht und der Text danach. Dann haben wir shiftdas Ergebnis, um die gesamte Zeichenfolge match ( splits[0]) loszuwerden .

Matthew Flaschen
quelle
1
Richtig, das sollte wohl am Anfang verankern. Javascript Regexen scheint jedoch gierig zu sein.
Muhmuhten
6

ein Liner und imo, einfacher:

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

Dies gibt "bin super | cool | ja!"

Hassek
quelle
3
Dies ist nicht das, wonach gefragt wurde, sie suchen auch nach dem fehlenden ersten Teil.
SmujMaiku
5

Die ES6-Syntax ermöglicht einen anderen Ansatz:

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

Dies behandelt auch die Möglichkeit, dass die Zeichenfolge keine hat, |indem sie null zurückgibt, anstatt eine leere Zeichenfolge, die expliziter ist.

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]

Pas de Pipe? C'est null!

Ich habe diese Antwort hauptsächlich hinzugefügt, damit ich ein Wortspiel auf das Pipe-Symbol machen kann, aber auch, um die es6-Syntax zu demonstrieren - es ist erstaunlich, wie viele Leute sie immer noch nicht verwenden ...

andyhasit
quelle
3

Versuche dies:

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", '|');
Josh die Ware
quelle
3

Wenn die Zeichenfolge nicht das Trennzeichen enthält, gibt die NickCraver-Lösung weiterhin ein Array mit zwei Elementen zurück, wobei das zweite eine leere Zeichenfolge ist. Ich bevorzuge das Verhalten von Split. Das heißt, wenn die Eingabezeichenfolge das Trennzeichen nicht enthält, wird nur ein Array mit einem einzelnen Element zurückgegeben.

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"]
Raine Revere
quelle
1

Genauso böse wie die meisten bisherigen Antworten:

var splits = str.split('|');
splits.splice(1, splits.length - 1, splits.slice(1).join('|'));
Wombleton
quelle
0

Ein alternativer, kurzer Ansatz besteht neben den anderen Waren darin, das replace()Limit zu Ihrem Vorteil zu nutzen.

var str = "1|Ceci n'est pas une pipe: | Oui";
str.replace("|", "aUniquePhraseToSaySplitMe").split("aUniquePhraseToSaySplitMe");

Wie @sreservoir in den Kommentaren hervorhebt, muss die eindeutige Phrase wirklich eindeutig sein - sie darf nicht in der Quelle enthalten sein, über die Sie diese Aufteilung ausführen, oder Sie erhalten die Zeichenfolge in mehr Teile aufgeteilt, als Sie möchten. Ein nicht druckbares Zeichen kann, wie er sagt, funktionieren, wenn Sie dies gegen Benutzereingaben ausführen (dh in einem Browser eingeben).


quelle
Das funktioniert nur, wenn die 'eindeutige' Phrase nicht unbestreitbar ist. Wenn Sie aus einer Textdatei lesen, ist dies nicht möglich. Wenn Sie aus dem Browser lesen, ist jedes nicht druckbare Steuerzeichen wahrscheinlich in Ordnung. Tab wirkt auch Wunder. In jedem Fall ist "aUniquePhraseToSaySplitMe" mit ziemlicher Sicherheit Teil der Eingabe und daher gefährlich.
Muhmuhten
Sie haben natürlich Recht. Mein Beispiel ist nur ein Beispiel, um zu erklären, was kurz gemacht wird. Ich werde Ihren Punkt in die Antwort selbst einbeziehen. Vielen Dank!
Wenn Sie str für Ihre eindeutige Phrase verwenden, wissen Sie, dass sie nicht wieder vorhanden sein kann! : böses Grinsen
Fabio Beltramini
0

Dies ist ein bisschen länger, aber es funktioniert so, wie ich glaube, dass die Grenze:

function split_limit(inString, separator, limit){
    var ary = inString.split(separator);
    var aryOut = ary.slice(0, limit - 1);
    if(ary[limit - 1]){
        aryOut.push(ary.slice(limit - 1).join(separator));
    }
    return aryOut;
}
console.log(split_limit("1|Ceci n'est pas une pipe: | Oui","|", 1));
console.log(split_limit("1|Ceci n'est pas une pipe: | Oui","|", 2));
console.log(split_limit("1|Ceci n'est pas une pipe: | Oui","|", 3));
console.log(split_limit("1|Ceci n'est pas une pipe: | Oui","|", 7));

https://jsfiddle.net/2gyxuo2j/

limit of Zero liefert lustige Ergebnisse, aber im Namen der Effizienz habe ich die Prüfung dafür weggelassen. Sie können dies als erste Zeile der Funktion hinzufügen, wenn Sie es benötigen:

if(limit < 1) return [];
alfadog67
quelle
0

Wenn Sie eine "Pipeline" verwenden möchten, reduceist Ihr Freund

const separator = '|'
jsonNode.split(separator)
   .reduce((previous, current, index) =>
    {
        if (index < 2) previous.push(current)
        else previous[1] += `${separator}${current}`
        return previous
    }, [])
    .map((item: string) => (item.trim()))
    .filter((item: string) => (item != ''))
verrücktx13
quelle
0

Effektivere Methode:

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);

edvard chen
quelle
-1

Verwenden Sie die Funktion für reguläre Javascript-Ausdrücke und nehmen Sie den ersten erfassten Ausdruck.

Der RE würde wahrscheinlich so aussehen /^([^|]*)\|/.

Eigentlich brauchen Sie nur, /[^|]*/wenn Sie überprüft haben, dass die Zeichenfolge aufgrund der Gier von Javascript-Regex so formatiert ist.

muhmuhten
quelle