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

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"

Обратите внимание, что если пробела нет вообще, то первая строка вернет пустую строку, а вторая строка вернет всю строку. Будьте уверены, что именно такое поведение вы хотите в этой ситуации (или что эта ситуация не возникнет).

Trott
источник
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)

Georg
источник
str.match(/^(\S+)\s(.*)/).slice(1) не будет работать для строки, которая не имеет места
Джунаид
30

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

let [first, ...second] = str.split(" ")
second = second.join(" ")
user1652176
источник
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
fpscolin
источник
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

Rotareti
источник
Как это! Есть "минусы"?
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 

Я уверен, что это может быть сжато в меньше строк, но я оставил его расширенным для удобства чтения.

acarito
источник
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;
}
Сьорд Линдерс
источник
Это слишком сложно .
Дан Дакалеску