Seqüência de caracteres dividida na primeira ocorrência de espaço em branco

149

Não recebi um regex otimizado que me dividiu uma String com base na primeira ocorrência de espaço em branco:

var str="72 tocirah sneab";

Eu preciso obter:

[
    "72",
    "tocirah sneab",
]
Luca
fonte
1
O que você quer dizer com "otimizado"? Será que ela tem que ser um regex?
Deestan
Por favor, tome o tempo para rolar para baixo para @ Georg, em resposta - bela stackoverflow.com/a/10272828/93910
Sanjay Manohar

Respostas:

323

Se você se importa apenas com o caractere de espaço (e não com guias ou outros caracteres de espaço em branco) e se preocupa apenas com tudo antes do primeiro espaço e depois do primeiro espaço, é possível fazê-lo sem uma expressão regular como esta:

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

Observe que, se não houver espaço, a primeira linha retornará uma string vazia e a segunda linha retornará a string inteira. Certifique-se de que é o comportamento que você deseja nessa situação (ou que essa situação não ocorra).

Trott
fonte
49

Javascript não suporta lookbehinds, então splitnão é possível. matchtrabalho:

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

Outro truque:

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

e quanto a:

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

e porque não

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

ou talvez

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

Atualização de 2019 : a partir do ES2018, há suporte para lookbehinds:

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

georg
fonte
str.match(/^(\S+)\s(.*)/).slice(1) vai trabalhar para uma string que não tem espaço
Junaid
30

No ES6, você também pode

let [first, ...second] = str.split(" ")
second = second.join(" ")
user1652176
fonte
2
Gostei bastante disso e funciona bem, mas em termos de desempenho é muito ruim para a solução de "substring" mais votada. apenas testei e é cerca de 10x mais lento.
pootzko
18

Tarde para o jogo, eu sei, mas parece haver uma maneira muito simples de fazer isso:

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

Isso sairá arr[0]com "72"e arr[1]com "tocirah sneab". Note que arr [2] estará vazio, mas você pode simplesmente ignorá-lo.

Para referência:

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

Cliff Stanford
fonte
Observe que isso produz um último elemento em branco.
Benjamin Intal 11/06
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"];

mas ainda acho que existe uma maneira mais rápida.

Joseph
fonte
11

A solução do georg é boa, mas é interrompida se a string não contiver nenhum espaço em branco. Se suas seqüências de caracteres tiverem a chance de não conter espaços em branco, é mais seguro usar .split e capturar grupos como este:

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

Você também pode usar .replace para substituir apenas a primeira ocorrência,

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

Deixando de fora o / g.

DEMO

Daedalus
fonte
3
@DannyHerran .. Não, não vai? Você já testou o código? Não há modificador / g. Não é global. Tente testar o código antes de saber o que ele faz . Testado nos três principais navegadores também. Eu gostaria de saber por que você pensa o que faz.
Daedalus
Isso é inteligente, porque sempre considerei isso um defeito. Esta é a primeira vez que eu estou vendo isso é aproveitado :)
Gogol
2

Basta dividir a corda em uma matriz e colar as peças necessárias. Essa abordagem é muito flexível, funciona em muitas situações e é fácil de raciocinar. Além disso, você só precisa de uma chamada de função.

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

Como alternativa, se você quiser escolher o que precisa diretamente da string, poderá fazer algo assim:

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

Ou assim:

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

No entanto, sugiro o primeiro exemplo.

Demonstração de trabalho: jsbin

Rotareti
fonte
Como isso! Tem "contras"?
iglesiasedd
0

Sempre que eu preciso obter uma classe de uma lista de classes ou parte de um nome ou ID de classe, eu sempre uso split (), em seguida, obtenha-a especificamente com o índice de matriz ou, na maioria dos casos, pop () para obter o último elemento ou shift () para obter o primeiro.

Este exemplo obtém as classes da div "gallery_148 ui-classable" e retorna o ID da galeria 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 

Tenho certeza de que poderia ser compactado em menos linhas, mas o deixei expandido para facilitar a leitura.

acarito
fonte
0

Eu precisava de um resultado um pouco diferente.

Eu queria a primeira palavra, e o que veio depois dela - mesmo que estivesse em branco.

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

então se a entrada é que onewordvocê recebe oneworde ''.

Se a entrada é que one word and some morevocê recebe onee word and some more.

Jim Richards
fonte
0

Não sei por que todas as outras respostas são tão complicadas, quando você pode fazer tudo em uma linha, lidando com a falta de espaço também.

Como exemplo, vamos obter o primeiro e "outros" componentes de um nome:

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

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

Dan Dascalescu
fonte
-1

A função a seguir sempre dividirá a frase em 2 elementos. O primeiro elemento conterá apenas a primeira palavra e o segundo elemento conterá todas as outras palavras (ou será uma sequência vazia).

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
fonte
Isso é muito complicado .
Dan Dascalescu