División de cadena en la primera aparición de espacio en blanco

150

No obtuve una expresión regular optimizada que me dividió una cadena basada en la primera aparición de espacio en blanco:

var str="72 tocirah sneab";

Necesito conseguir:

[
    "72",
    "tocirah sneab",
]
Luca
fuente
1
¿Qué quieres decir con "optimizado"? ¿ Tiene que ser una expresión regular?
Deestan
Tómese el tiempo para desplazarse hacia abajo a la respuesta de @ georg - beautiful stackoverflow.com/a/10272828/93910
Sanjay Manohar

Respuestas:

324

Si solo te importa el carácter de espacio (y no las pestañas u otros caracteres de espacio en blanco) y solo te importa todo antes del primer espacio y todo después del primer espacio, puedes hacerlo sin una expresión regular como esta:

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

Tenga en cuenta que si no hay espacio, la primera línea devolverá una cadena vacía y la segunda línea devolverá toda la cadena. Asegúrese de que ese sea el comportamiento que desea en esa situación (o que esa situación no surja).

Trott
fuente
50

Javascript no soporta lookbehinds, así splitque no es posible matchtrabajos:

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

Otro truco:

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

qué tal si:

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

y por qué no

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

o tal vez

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

Actualización de 2019 : a partir de ES2018, se admiten lookbehinds:

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

georg
fuente
str.match(/^(\S+)\s(.*)/).slice(1) no funcionará para una cadena que no tiene espacio
Junaid
30

En ES6 también puedes

let [first, ...second] = str.split(" ")
second = second.join(" ")
usuario1652176
fuente
2
Me gustó bastante y funciona bien, pero el rendimiento es bastante malo para la solución de "subcadena" más votada. solo lo probé y es aproximadamente 10 veces más lento.
pootzko
19

Al final del juego, lo sé, pero parece que hay una manera muy simple de hacer esto:

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

Esto saldrá arr[0]con "72"y arr[1]con "tocirah sneab". Tenga en cuenta que arr [2] estará vacío, pero puede ignorarlo.

Para referencia:

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

Un acantilado
fuente
Tenga en cuenta que esto produce un último elemento en blanco.
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"];

Pero todavía creo que hay una manera más rápida.

Joseph
fuente
11

La solución de georg es buena, pero se rompe si la cadena no contiene ningún espacio en blanco. Si sus cadenas tienen la posibilidad de no contener espacios en blanco, es más seguro usar .split y capturar grupos de esta manera:

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

También puede usar .replace para reemplazar solo la primera aparición,

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

Dejando fuera el / g.

MANIFESTACIÓN

Dédalo
fuente
3
@DannyHerran .. No, no lo hará? ¿Has probado el código? No hay modificador / g. No es global. Intente probar el código antes de decir lo que hace . Probado en los tres principales navegadores también. Me gustaría saber por qué piensas lo que haces.
Dédalo
Eso es inteligente porque siempre he considerado esto como un defecto. Esta es la primera vez que veo que esto se aprovecha :)
Gogol
2

Simplemente divida la cadena en una matriz y pegue las partes que necesita juntas. Este enfoque es muy flexible, funciona en muchas situaciones y es fácil razonar. Además, solo necesita una llamada de función.

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

Alternativamente, si desea seleccionar lo que necesita directamente de la cadena, puede hacer algo como esto:

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

O así:

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

Sin embargo, sugiero el primer ejemplo.

Demostración de trabajo: jsbin

Rotareti
fuente
¡Me gusta esto! ¿Tienes "contras"?
iglesiasedd
0

Siempre que necesito obtener una clase de una lista de clases o una parte de un nombre o id de clase, siempre uso split () y luego lo obtengo específicamente con el índice de matriz o, más a menudo en mi caso, pop () para obtener el último elemento o shift () para obtener el primero.

Este ejemplo obtiene las clases del div "gallery_148 ui-sortable" y devuelve el id de la galería 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 

Estoy seguro de que podría compactarse en menos líneas, pero lo dejé expandido para facilitar la lectura.

acarito
fuente
0

Necesitaba un resultado ligeramente diferente.

Quería la primera palabra, y lo que vino después, incluso si estaba en blanco.

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

así que si la entrada se onewordobtiene onewordy'' .

Si la entrada es one word and some moreusted obtiene oney word and some more.

Jim Richards
fuente
0

No estoy seguro de por qué todas las otras respuestas son tan complicadas, cuando puedes hacerlo todo en una línea, manejando la falta de espacio también.

Como ejemplo, obtengamos los primeros y "otros" componentes de un nombre:

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

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

Dan Dascalescu
fuente
-1

La siguiente función siempre dividirá la oración en 2 elementos. El primer elemento contendrá solo la primera palabra y el segundo elemento contendrá todas las otras palabras (o será una cadena vacía).

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
fuente
Esto es demasiado complicado .
Dan Dascalescu