Geteilte Zeichenfolge beim ersten Auftreten von Leerzeichen

149

Ich habe keinen optimierten regulären Ausdruck erhalten, der mich in einen String aufteilt, der auf dem ersten Leerraum basiert:

var str="72 tocirah sneab";

Ich benötige:

[
    "72",
    "tocirah sneab",
]
Luca
quelle
1
Was meinst du mit "optimiert"? Ist es habe eine Regex sein?
Deestan
Bitte nehmen Sie sich die Zeit, um nach unten zu @ Georgs
Sanjay Manohar

Antworten:

323

Wenn Sie sich nur um das Leerzeichen (und nicht um Tabulatoren oder andere Leerzeichen) kümmern und sich nur um alles vor dem ersten Leerzeichen und alles nach dem ersten Leerzeichen kümmern, können Sie dies ohne einen regulären Ausdruck wie diesen tun:

str.substr(0,str.indexOf(' ')); // "72"
str.substr(str.indexOf(' ')+1); // "tocirah sneab"

Beachten Sie, dass in der ersten Zeile eine leere Zeichenfolge und in der zweiten Zeile die gesamte Zeichenfolge zurückgegeben wird, wenn überhaupt kein Leerzeichen vorhanden ist. Stellen Sie sicher, dass dies das Verhalten ist, das Sie in dieser Situation wünschen (oder dass diese Situation nicht auftritt).

Trott
quelle
49

Javascript unterstützt keine Lookbehinds, splitist also nicht möglich. matchfunktioniert:

str.match(/^(\S+)\s(.*)/).slice(1)

Ein weiterer Trick:

str.replace(/\s+/, '\x01').split('\x01')

wie wäre es mit:

[str.replace(/\s.*/, ''), str.replace(/\S+\s/, '')]

und warum nicht

reverse = function (s) { return s.split('').reverse().join('') }
reverse(str).split(/\s(?=\S+$)/).reverse().map(reverse)

oder vielleicht

re = /^\S+\s|.*/g;
[].concat.call(re.exec(str), re.exec(str))

Update 2019 : Ab ES2018 werden Lookbehinds unterstützt:

str = "72 tocirah sneab"
s = str.split(/(?<=^\S+)\s/)
console.log(s)

georg
quelle
str.match(/^(\S+)\s(.*)/).slice(1) funktioniert nicht für eine Zeichenfolge, die keinen Platz hat
Junaid
29

In ES6 können Sie auch

let [first, ...second] = str.split(" ")
second = second.join(" ")
user1652176
quelle
2
Ich mochte das ziemlich und es funktioniert gut, aber in Bezug auf die Leistung ist es ziemlich schlecht für die am besten bewertete "Teilstring" -Lösung. habe es gerade getestet und es ist ungefähr 10x langsamer.
Pootzko
18

Ich weiß, dass ich zu spät zum Spiel komme, aber es scheint einen sehr einfachen Weg zu geben, dies zu tun:

const str = "72 tocirah sneab";
const arr = str.split(/ (.*)/);
console.log(arr);

Dies wird arr[0]mit "72"und arr[1]mit verlassen"tocirah sneab" . Beachten Sie, dass arr [2] leer ist, Sie es jedoch einfach ignorieren können.

Als Referenz:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split#Capturing_parentheses

Cliff Stanford
quelle
Beachten Sie, dass dies ein letztes leeres Element erzeugt.
Benjamin Intal
13
var arr = [];             //new storage
str = str.split(' ');     //split by spaces
arr.push(str.shift());    //add the number
arr.push(str.join(' '));  //and the rest of the string

//arr is now:
["72","tocirah sneab"];

aber ich denke immer noch, dass es einen schnelleren Weg gibt.

Joseph
quelle
11

Georgs Lösung ist nett, bricht aber, wenn die Zeichenfolge kein Leerzeichen enthält. Wenn Ihre Zeichenfolgen möglicherweise keine Leerzeichen enthalten, ist es sicherer, .split zu verwenden und Gruppen wie folgt zu erfassen:

str_1 = str.split(/\s(.+)/)[0];  //everything before the first space
str_2 = str.split(/\s(.+)/)[1];  //everything after the first space
fpscolin
quelle
9

Sie können .replace auch verwenden, um nur das erste Vorkommen zu ersetzen.

str = str.replace(' ','<br />');

Das / g weglassen.

DEMO

Daedalus
quelle
3
@DannyHerran .. Nein, wird es nicht? Haben Sie den Code überhaupt getestet? Es gibt keinen / g-Modifikator. Es ist nicht global. Versuchen Sie, den Code zu testen, bevor Sie vorgeben, zu wissen, was er tut . Auch in den drei Hauptbrowsern getestet. Ich würde gerne wissen, warum Sie denken, was Sie tun.
Daedalus
Das ist klug, weil ich das immer als Defekt angesehen habe. Dies ist das erste Mal, dass ich sehe, dass dies ausgenutzt wird :)
Gogol
2

Teilen Sie einfach die Zeichenfolge in ein Array und kleben Sie die benötigten Teile zusammen. Dieser Ansatz ist sehr flexibel, funktioniert in vielen Situationen und ist leicht zu überlegen. Außerdem benötigen Sie nur einen Funktionsaufruf.

arr = str.split(' ');             // ["72", "tocirah", "sneab"]
strA = arr[0];                    // "72"
strB = arr[1] + ' ' + arr[2];     // "tocirah sneab"

Alternativ können Sie Folgendes tun, wenn Sie direkt aus der Zeichenfolge auswählen möchten, was Sie benötigen:

strA = str.split(' ')[0];                    // "72";
strB = str.slice(strA.length + 1);           // "tocirah sneab"

Oder so:

strA = str.split(' ')[0];                    // "72";
strB = str.split(' ').splice(1).join(' ');   // "tocirah sneab"

Ich schlage jedoch das erste Beispiel vor.

Arbeitsdemo : jsbin

Rotareti
quelle
So was! Haben Sie "Nachteile"?
iglesiasedd
0

Wenn ich eine Klasse aus einer Liste von Klassen oder einem Teil eines Klassennamens oder einer ID abrufen muss, verwende ich immer split () und erhalte sie dann entweder speziell mit dem Array-Index oder, in meinem Fall meistens, mit pop () das letzte Element oder shift (), um das erste zu erhalten.

In diesem Beispiel werden die Klassen des div "gallery_148 ui-sortable" abgerufen und die Galerie-ID 148 zurückgegeben.

var galleryClass = $(this).parent().prop("class"); // = gallery_148 ui-sortable
var galleryID = galleryClass.split(" ").shift(); // = gallery_148
galleryID = galleryID.split("_").pop(); // = 148
//or
galleryID = galleryID.substring(8); // = 148 also, but less versatile 

Ich bin sicher, dass es in weniger Zeilen komprimiert werden könnte, aber ich habe es zur besseren Lesbarkeit erweitert gelassen.

Acarito
quelle
0

Ich brauchte ein etwas anderes Ergebnis.

Ich wollte das erste Wort und was auch immer danach kam - auch wenn es leer war.

str.substr(0, text.indexOf(' ') == -1 ? text.length : text.indexOf(' '));
str.substr(text.indexOf(' ') == -1 ? text.length : text.indexOf(' ') + 1);

Also, wenn die Eingabe ist, erhalten onewordSie onewordund ''.

Wenn die Eingabe ist, erhalten one word and some moreSie oneund word and some more.

Jim Richards
quelle
0

Ich bin mir nicht sicher, warum alle anderen Antworten so kompliziert sind, wenn Sie alles in einer Zeile erledigen können und auch den Platzmangel bewältigen.

Lassen Sie uns als Beispiel die erste und "andere" Komponente eines Namens erhalten:

let [first, last] = 'John Von Doe'.split(/ (.*)/);
console.log({ first, last });

[first, last] = 'Surma'.split(/ (.*)/);
console.log({ first, last });

Dan Dascalescu
quelle
-1

Die folgende Funktion wird immer geteilt , den Satz in 2 Elemente. Das erste Element enthält nur das erste Wort und das zweite Element enthält alle anderen Wörter (oder es ist eine leere Zeichenfolge).

var arr1 = split_on_first_word("72 tocirah sneab");       // Result: ["72", "tocirah sneab"]
var arr2 = split_on_first_word("  72  tocirah sneab  ");  // Result: ["72", "tocirah sneab"]
var arr3 = split_on_first_word("72");                     // Result: ["72", ""]
var arr4 = split_on_first_word("");                       // Result: ["", ""]

function split_on_first_word(str)
{
    str = str.trim();  // Clean string by removing beginning and ending spaces.

    var arr = [];
    var pos = str.indexOf(' ');  // Find position of first space

    if ( pos === -1 ) {
        // No space found
        arr.push(str);                // First word (or empty)
        arr.push('');                 // Empty (no next words)
    } else {
        // Split on first space
        arr.push(str.substr(0,pos));         // First word
        arr.push(str.substr(pos+1).trim());  // Next words
    }

    return arr;
}
Sjoerd Linders
quelle
Das ist viel zu kompliziert .
Dan Dascalescu