Разделить строку на первое вхождение пробела


150

Я не получил оптимизированное регулярное выражение, которое разделило бы меня String, основываясь на первом появлении пробела:

var str="72 tocirah sneab";

Мне нужно получить:

[
    "72",
    "tocirah sneab",
]

1
Что вы подразумеваете под "оптимизирован"? Это должно быть регулярное выражение?
Дестан

Пожалуйста, найдите время, чтобы прокрутить вниз до ответа @ georg - beautiful 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 .. Нет, не будет? Вы даже тестировали код? Модификатора / g нет. Это не глобально. Попробуйте протестировать код, прежде чем заявить, что он делает . Протестировано также в трех основных браузерах. Я хотел бы знать, почему вы думаете, что вы делаете.
Дедал

Это умно, потому что я всегда считал это недостатком. Я впервые вижу, что этим пользуются :)
Гоголь

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.