Розділити рядок на першому появі пробілу


150

Я не отримав оптимізований регулярний вираз, який розділив мені String на основі першого появи білого простору:

var str="72 tocirah sneab";

Мені потрібно дістати:

[
    "72",
    "tocirah sneab",
]

1
Що ви маєте на увазі під «оптимізованим»? Чи повинен це бути регулярний вираз?
Діестан

Будь ласка, знайдіть час, щоб прокрутити вниз до відповіді @ georg - красивий stackoverflow.com/a/10272828/93910
Санджай Манохар

Відповіді:


324

Якщо ви дбаєте лише про пробільний символ (а не вкладки чи інші символи пробілу) і дбаєте лише про все перед першим пробілом та про все після першого пробілу, ви можете зробити це без регулярного виразу, як це:

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

Зауважте, що якщо місця зовсім немає, то перший рядок поверне порожній рядок, а другий - весь рядок. Будьте впевнені, що це поведінка, якої ви хочете в цій ситуації (або що така ситуація не виникне).


50

Javascript не підтримує вигляд, тому splitце неможливо. matchпрацює:

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

Ще одна хитрість:

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

як щодо:

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

а чому ні

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

або можливо

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

Оновлення 2019 року : станом на ES2018 підтримуються перспективи:

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


str.match(/^(\S+)\s(.*)/).slice(1) не будемо працювати над струною, якій немає місця
Джунайд

30

В ES6 ви також можете

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

2
Мені це сподобалося зовсім небагато, і він працює чудово, але ефективність мудра, це дуже погано для найбільш схваленого рішення "підрядка". просто перевірив це, і це приблизно в 10 разів повільніше.
pootzko

19

Я знаю, що пізно до гри, але, здається, існує дуже простий спосіб зробити це:

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

Це піде arr[0]з "72"і arr[1]з "tocirah sneab". Зауважте, що arr [2] буде порожнім, але ви можете просто проігнорувати його.

Довідково:

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


Зауважте, що це створює останній порожній елемент.
Бенджамін Інталь

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

але я все ще думаю, що існує більш швидкий шлях.


11

Рішення georg є приємним, але розривається, якщо рядок не містить пробілів. Якщо у ваших рядків є можливість не містити пробілів, безпечніше використовувати .split та групи захоплення таким чином:

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

9

Ви також можете використовувати .replace лише для заміни першого події,

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

Позбавлення / г.

DEMO


3
@DannyHerran .. Ні, це не буде? Ви навіть тестували код? Немає г / г модифікатора. Це не глобально. Спробуйте протестувати код, перш ніж ви плануєте знати, що він робить . Тестували також у трьох основних браузерах. Мені хотілося б знати, чому ти думаєш, що робиш.
Дедал

Це розумно, тому що я завжди вважав це дефектом. Це перший раз, коли я бачу, як цим скористатися :)
Гоголь

2

Просто розділіть рядок на масив і склейте разом потрібні вам частини. Цей підхід є дуже гнучким, він працює у багатьох ситуаціях, і це легко міркувати. Плюс вам потрібен лише один виклик функції.

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

Крім того, якщо ви хочете вишнево вибрати те, що вам потрібно безпосередньо із струни, ви можете зробити щось подібне:

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

Або так:

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

Однак я пропоную перший приклад.

Робоча демонстрація: jsbin


Подобається це! У вас є "мінуси"?
iglesiasedd

0

Кожного разу, коли мені потрібно отримати клас зі списку класів або частини імені або ідентифікатора класу, я завжди використовую split (), тоді або отримую його конкретно з індексом масиву, або, найчастіше в моєму випадку, pop (), щоб отримати останній елемент або shift (), щоб отримати перший.

Цей приклад отримує класи div "gallery_148 ui-sortable" і повертає ідентифікатор галереї 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 

Я впевнений, що його можна було ущільнити на менше рядків, але я залишив його розширеним для читання.


0

Мені потрібен був дещо інший результат.

Я хотів першого слова, і що коли-небудь після нього - навіть якщо воно було порожнім.

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

тож якщо вхід - onewordви отримаєте onewordі ''.

Якщо вхід - one word and some moreви отримаєте oneі word and some more.


0

Я не впевнений, чому всі інші відповіді настільки складні, коли ви можете зробити це все в один рядок, впораючись і з нестачею місця.

Як приклад, наведемо перший та "інші" компоненти імені:

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

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


-1

Наступна функція завжди розділяє речення на 2 елементи. Перший елемент буде містити лише перше слово, а другий - всі інші слова (або це буде порожній рядок).

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.