Podziel ciąg przy pierwszym wystąpieniu odstępu


150

Nie otrzymałem zoptymalizowanego wyrażenia regularnego, które podzieliło łańcuch String na podstawie pierwszego wystąpienia białej spacji:

var str="72 tocirah sneab";

Potrzebuję:

[
    "72",
    "tocirah sneab",
]

1
Co rozumiesz przez „zoptymalizowany”? Czy to musi być wyrażenie regularne?
Deestan

Poświęć trochę czasu, aby przewinąć w dół do odpowiedzi @ georg - piękny stackoverflow.com/a/10272828/93910
Sanjay Manohar

Odpowiedzi:


324

Jeśli zależy Ci tylko na znaku spacji (a nie na tabulatorach lub innych białych znakach) i zależy Ci tylko na wszystkim przed pierwszą spacją i wszystkim po pierwszej spacji, możesz to zrobić bez wyrażenia regularnego, takiego jak to:

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

Zauważ, że jeśli w ogóle nie ma spacji, pierwsza linia zwróci pusty ciąg, a druga zwróci cały ciąg. Upewnij się, że jest to zachowanie, którego chcesz w tej sytuacji (lub że taka sytuacja nie nastąpi).


50

Javascript nie obsługuje lookbehind, więc splitnie jest to możliwe. matchPracuje:

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

Kolejna sztuczka:

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

Co powiesz na:

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

czemu nie

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

albo może

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

Aktualizacja 2019 : od ES2018 obsługiwane są lookbehinds:

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


str.match(/^(\S+)\s(.*)/).slice(1) nie zadziała dla łańcucha, który nie ma spacji
Junaid

30

W ES6 możesz też

let [first, ...second] = str.split(" ")
second = second.join(" ")

2
Spodobało mi się to całkiem i działa dobrze, ale jeśli chodzi o wydajność, jest to dość kiepskie rozwiązanie w stosunku do najpopularniejszego rozwiązania „podciągowego”. właśnie go przetestowałem i jest około 10 razy wolniejszy.
pootzko

19

Wiem, że gra jest spóźniona, ale wydaje się, że jest na to bardzo prosty sposób:

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

To pozostawi arr[0]z "72"i arr[1]z "tocirah sneab". Zauważ, że arr [2] będzie pusty, ale możesz go po prostu zignorować.

Na przykład:

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


Zauważ, że to tworzy ostatni pusty element.
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"];

ale nadal uważam, że istnieje szybszy sposób.


11

Rozwiązanie Georga jest fajne, ale psuje się, jeśli łańcuch nie zawiera żadnych białych znaków. Jeśli twoje łańcuchy mogą nie zawierać białych znaków, bezpieczniej jest użyć .split i przechwytywania grup, takich jak:

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

9

Możesz także użyć .replace, aby zamienić tylko pierwsze wystąpienie,

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

Pomijając / g.

PRÓBNY


3
@DannyHerran .. Nie, nie będzie? Czy w ogóle przetestowałeś kod? Nie ma modyfikatora / g. To nie jest globalne. Spróbuj przetestować kod, zanim zaczniesz twierdzić, że wiesz, co on robi . Przetestowano również w trzech głównych przeglądarkach. Chciałbym wiedzieć, dlaczego myślisz o tym, co robisz.
Daedalus,

To sprytne, ponieważ zawsze uważałem to za wadę. To pierwszy raz, kiedy widzę, że jest to wykorzystywane :)
Gogol

2

Po prostu podziel sznurek na tablicę i sklej ze sobą potrzebne części. Takie podejście jest bardzo elastyczne, sprawdza się w wielu sytuacjach i łatwo się nad nim zastanawiać. Dodatkowo potrzebujesz tylko jednego wywołania funkcji.

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

Alternatywnie, jeśli chcesz wybrać coś, czego potrzebujesz bezpośrednio ze sznurka, możesz zrobić coś takiego:

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

Lub tak:

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

Jednak proponuję pierwszy przykład.

Działające demo: jsbin


Lubię to! Masz „wady”?
iglesiasedd

0

Ilekroć potrzebuję pobrać klasę z listy klas lub części nazwy klasy lub identyfikatora, zawsze używam metody split (), a następnie pobieram ją specjalnie z indeksem tablicy lub, najczęściej w moim przypadku, pop (), aby uzyskać ostatni element lub shift (), aby uzyskać pierwszy.

Ten przykład pobiera klasy div „gallery_148 ui-sortable” i zwraca identyfikator galerii 148.

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 

Jestem pewien, że można by go skompresować do mniejszej liczby wierszy, ale zostawiłem go rozszerzony dla większej czytelności.


0

Potrzebowałem nieco innego wyniku.

Chciałem pierwszego słowa i tego, co po nim przyszło - nawet jeśli było puste.

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

więc jeśli dane wejściowe to onewordotrzymasz onewordi'' .

Jeśli dane wejściowe to one word and some moreotrzymasz onei word and some more.


0

Nie jestem pewien, dlaczego wszystkie inne odpowiedzi są tak skomplikowane, skoro można to wszystko zrobić w jednej linii, radząc sobie również z brakiem miejsca.

Jako przykład weźmy pierwszy i „pozostałe” składniki nazwy:

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

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


-1

Następująca funkcja zawsze podzieli zdanie na 2 elementy. Pierwszy element będzie zawierał tylko pierwsze słowo, a drugi element będzie zawierał wszystkie pozostałe słowa (lub będzie to pusty ciąg).

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

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.