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 ...

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


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

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 .


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!"


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 ...


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", '|');

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"]

1

Genauso böse wie die meisten bisherigen Antworten:

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

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


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 [];

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 != ''))

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


-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.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.