¿Cómo divido una cadena con varios separadores en JavaScript?
Frecuentes
Visto 581,888 equipos
569
¿Cómo divido una cadena con varios separadores en JavaScript?
Estoy tratando de dividirme en ambos comas y espacios, pero AFAIK JavaScript split()
La función solo admite un separador.
22 Respuestas
787
Pase una expresión regular como parámetro:
js> "Hello awesome, world!".split(/[\s,]+/)
Hello,awesome,world!
Editado para agregar:
Puede obtener el último elemento seleccionando la longitud de la matriz menos 1:
>>> bits = "Hello awesome, world!".split(/[\s,]+/)
["Hello", "awesome", "world!"]
>>> bit = bits[bits.length - 1]
"world!"
... y si el patrón no coincide:
>>> bits = "Hello awesome, world!".split(/foo/)
["Hello awesome, world!"]
>>> bits[bits.length - 1]
"Hello awesome, world!"
respondido 16 mar '09, 19:03
¿Qué estás usando para tu js> consola? - core
rhino, la implementación de JavaScript de Mozilla en Java: mozilla.org/rhino (... o "sudo apt-get install rhino"). - Aarón Maenpaa
Gracias. otra pregunta relacionada con esto, lo que tengo que hacer es obtener el último elemento de la matriz dividida. si no hay una matriz, debería devolver la cadena thx - sol
¿Hay alguna forma de evitar eliminar los separadores al dividir con una expresión regular? - anderson verde
¿Cómo dividir tanto para una cadena "hola mundo" como para otro carácter (u otra expresión regular), como el símbolo de la tubería? Intenté variaciones de (hello world)|\|
que no funcionó del todo todavía. ¿Algunas ideas? - loco por natty
213
Puede pasar una expresión regular a JavaScript separar() método. Por ejemplo:
"1,2 3".split(/,| /)
["1", "2", "3"]
O, si quieres permitir múltiples separadores juntos para actuar como uno solo:
"1, 2, , 3".split(/(?:,| )+/)
["1", "2", "3"]
NB! Tienes que usar la no captura (?:)
paréntesis, porque de lo contrario se vuelve a empalmar en el resultado. O puedes ser inteligente como Aaron y usar una clase de personaje.
Ejemplos probados en Safari y Firefox.
respondido 01 mar '21, 15:03
Si necesita varios caracteres para actuar como uno, como en, diga "uno; # dos; # nueva camiseta", simplemente puede pasar la cadena "; #" a la función de división. "one; #two; #new jersey" .split ("; #") [2] === "new jersey" - oskar austegard
Este método funciona mejor que las clases de caracteres si necesita dividir en más de un carácter. Sepárelos por |
como muestra Jesse. - devios1
Me pregunto si hay una manera de evitar eliminar los separadores al dividir una cadena con una expresión regular: este ejemplo elimina los separadores, pero espero que sea posible dividir una cadena sin eliminarlos. - anderson verde
@AndersonGreen Depende exactamente de lo que quieras; en este caso, hay varios separadores, entonces, ¿desea conservarlos todos? ¿Como un artículo separado? ¿Te has unido al artículo anterior? ¿Proximo articulo? No me parece claro. Es posible que desee hacer una nueva pregunta con algunos ejemplos de lo que está buscando. - Jesse Rusak
@JesseRusak Me refería a mantener todos los separadores como elementos separados, de modo que una cadena pueda ser tokenizada usando una lista de separadores. - anderson verde
68
Otro método simple pero efectivo es usar split + join repetidamente.
"a=b,c:d".split('=').join(',').split(':').join(',').split(',')
Básicamente, hacer una división seguida de una combinación es como un reemplazo global, por lo que reemplaza cada separador con una coma y, una vez que se reemplazan todos, hace una división final en coma.
El resultado de la expresión anterior es:
['a', 'b', 'c', 'd']
Ampliando esto, también podría colocarlo en una función:
function splitMulti(str, tokens){
var tempChar = tokens[0]; // We can use the first token as a temporary join character
for(var i = 1; i < tokens.length; i++){
str = str.split(tokens[i]).join(tempChar);
}
str = str.split(tempChar);
return str;
}
Uso:
splitMulti('a=b,c:d', ['=', ',', ':']) // ["a", "b", "c", "d"]
Si usa mucho esta funcionalidad, incluso podría valer la pena considerar envolver String.prototype.split
por conveniencia (creo que mi función es bastante segura; la única consideración es la sobrecarga adicional de los condicionales (menor) y el hecho de que carece de una implementación del argumento límite si se pasa una matriz).
Asegúrese de incluir el splitMulti
función si se utiliza este enfoque para el siguiente simplemente lo envuelve :). También vale la pena señalar que algunas personas desaprueban la extensión de los elementos integrados (ya que muchas personas lo hacen mal y pueden ocurrir conflictos), por lo que, en caso de duda, hable con alguien de mayor edad antes de usar esto o pregunte en SO :)
var splitOrig = String.prototype.split; // Maintain a reference to inbuilt fn
String.prototype.split = function (){
if(arguments[0].length > 0){
if(Object.prototype.toString.call(arguments[0]) == "[object Array]" ) { // Check if our separator is an array
return splitMulti(this, arguments[0]); // Call splitMulti
}
}
return splitOrig.apply(this, arguments); // Call original split maintaining context
};
Uso:
var a = "a=b,c:d";
a.split(['=', ',', ':']); // ["a", "b", "c", "d"]
// Test to check that the built-in split still works (although our wrapper wouldn't work if it didn't as it depends on it :P)
a.split('='); // ["a", "b,c:d"]
¡Que la disfrutes!
respondido 18 mar '18, 01:03
Porque escribes for(var i = 0; i < tokens.length; i++)
y no for(var i = 1; i < tokens.length; i++)
? - tic
Me había perdido esa optimización, tienes razón, podemos empezar en tokens[1]
para guardar una iteración como tokens[0] == tempchar
y nos separamos tempchar
después de iterar sobre tokens
para terminar. Actualizaré la respuesta en consecuencia, gracias @tic :). - Brian
No es aconsejable jugar con prototipos. Las consideraciones generales son muy difíciles de tener en cuenta debido a las optimizaciones que ocurren en el fondo. Puede activar una bandera en C que diga 'si han modificado el prototipo, se supone que X ya no es seguro, recurra a esta ruta de código [mucho más lenta]' para una amplia variedad de funciones. Lo que parecía una 'sobrecarga baja' puede terminar ralentizando la ejecución de código optimizado en órdenes de magnitud. - Kyle Baker
No es bueno, porque si ya hubo un ,
en la cuerda, te dividirás, incluso si no lo quieres. - Broda Noel
@BrodaNoel, tienes razón, esa es la principal advertencia del primer ejemplo de código. En ese caso particular, es mejor usar un carácter en el que sea seguro dividir, en mi ejemplo, la intención era reemplazar el ,
por lo que era "seguro", pero ciertamente es algo a tener en cuenta. La splitMulti
El ejemplo aborda esto usando el primer token en la matriz como un marcador de posición temporal, ya que sabemos que queremos que se reemplacen todos, por lo que siempre es seguro usarlo :) - Brian
26
Hagámoslo simple: (agregue un "[] +" a su expresión regular significa "1 o más")
Esto significa que "+" y "{1,}" son iguales.
var words = text.split(/[ .:;?!~,`"&|()<>{}\[\]\r\n/\\]+/); // note ' and - are kept
Respondido el 04 de enero de 18 a las 04:01
agregar un "+" al final significa 1 o más - Asher
Yo diría que esto es mínimo, no simple. darryl hebbes
Para + y - :-D, pero también \ s en lugar del carácter en blanco: var words = text.split (/ [\ s.:;?!~,`"&|()<>{}\= \ + \ - [] \ r \ n / \] + /); - Didier68
14
Método complicado:
var s = "dasdnk asd, (naks) :d skldma";
var a = s.replace('(',' ').replace(')',' ').replace(',',' ').split(' ');
console.log(a);//["dasdnk", "asd", "naks", ":d", "skldma"]
Respondido 04 Jul 13, 14:07
esto es incorrecto porque .replace () no reemplaza todos los elementos :/
- usuario669677
tu puedes cambiar '('
para /(/g
para reemplazar todo (
elementos - g
son los global marca para RegExp, por lo que busca todas las apariciones de (
no el primero - nombre clave-
8
Para aquellos de ustedes que desean más personalización en su función de división, escribí un algoritmo recursivo que divide una cadena determinada con una lista de caracteres para dividir. Escribí esto antes de ver la publicación anterior. Espero que ayude a algunos programadores frustrados.
splitString = function(string, splitters) {
var list = [string];
for(var i=0, len=splitters.length; i<len; i++) {
traverseList(list, splitters[i], 0);
}
return flatten(list);
}
traverseList = function(list, splitter, index) {
if(list[index]) {
if((list.constructor !== String) && (list[index].constructor === String))
(list[index] != list[index].split(splitter)) ? list[index] = list[index].split(splitter) : null;
(list[index].constructor === Array) ? traverseList(list[index], splitter, 0) : null;
(list.constructor === Array) ? traverseList(list, splitter, index+1) : null;
}
}
flatten = function(arr) {
return arr.reduce(function(acc, val) {
return acc.concat(val.constructor === Array ? flatten(val) : val);
},[]);
}
var stringToSplit = "people and_other/things";
var splitList = [" ", "_", "/"];
splitString(stringToSplit, splitList);
El ejemplo anterior devuelve: ["people", "and", "other", "things"]
Nota: flatten
la función fue tomada de Código Rosetta
Respondido 04 Abr '17, 16:04
7
Puede agrupar todos los caracteres que desee utilizar como separadores, ya sea de forma individual o colectiva, en una expresión regular y pasarlos a la función de división. Por ejemplo, podrías escribir:
console.log( "dasdnk asd, (naks) :d skldma".split(/[ \(,\)]+/) );
Y la salida será:
["dasdnk", "asd", "naks", ":d", "skldma"]
Respondido 22 Abr '14, 05:04
5
Mi refactor de @Brian responde
var string = 'and this is some kind of information and another text and simple and some egample or red or text';
var separators = ['and', 'or'];
function splitMulti(str, separators){
var tempChar = 't3mp'; //prevent short text separator in split down
//split by regex e.g. \b(or|and)\b
var re = new RegExp('\\b(' + separators.join('|') + ')\\b' , "g");
str = str.replace(re, tempChar).split(tempChar);
// trim & remove empty
return str.map(el => el.trim()).filter(el => el.length > 0);
}
console.log(splitMulti(string, separators))
Respondido 15 Oct 19, 19:10
4
Hola, por ejemplo, si ha dividido y reemplazado en String 07:05:45 PM
var hour = time.replace("PM", "").split(":");
Resultado
[ '07', '05', '45' ]
respondido 09 mar '16, 13:03
3
Aquí hay una nueva forma de lograr lo mismo en ES6:
function SplitByString(source, splitBy) {
var splitter = splitBy.split('');
splitter.push([source]); //Push initial value
return splitter.reduceRight(function(accumulator, curValue) {
var k = [];
accumulator.forEach(v => k = [...k, ...v.split(curValue)]);
return k;
});
}
var source = "abc,def#hijk*lmn,opq#rst*uvw,xyz";
var splitBy = ",*#";
console.log(SplitByString(source, splitBy));
Tenga en cuenta en esta función:
- No Regex involucrado
- Devuelve el valor dividido en el mismo orden en que aparece en
source
El resultado del código anterior sería:
Respondido el 24 de junio de 19 a las 14:06
¿Qué pasa si lo que quiero dividir es por "hola" y "ciao"? - Broda Noel
@BrodaNoel modificar splitBy.split('')
a sus necesidades. No se porque SplitByString()
no está diseñado para aceptar una matriz como parámetro de inmediato, por lo que nadie tiene que adivinar dónde dividir nada. - AmigoJack
3
Proporcionaré una implementación clásica para tal función. El código funciona en casi todas las versiones de JavaScript y de alguna manera es óptimo.
- No usa expresiones regulares, que es difícil de mantener.
- No utiliza nuevas funciones de JavaScript.
- No utiliza múltiples invocaciones .split () .join () que requieren más memoria de computadora
Solo código puro:
var text = "Create a function, that will return an array (of string), with the words inside the text";
println(getWords(text));
function getWords(text)
{
let startWord = -1;
let ar = [];
for(let i = 0; i <= text.length; i++)
{
let c = i < text.length ? text[i] : " ";
if (!isSeparator(c) && startWord < 0)
{
startWord = i;
}
if (isSeparator(c) && startWord >= 0)
{
let word = text.substring(startWord, i);
ar.push(word);
startWord = -1;
}
}
return ar;
}
function isSeparator(c)
{
var separators = [" ", "\t", "\n", "\r", ",", ";", ".", "!", "?", "(", ")"];
return separators.includes(c);
}
Puede ver el código que se ejecuta en el patio de recreo: https://codeguppy.com/code.html?IJI0E4OGnkyTZnoszAzf
Respondido el 07 de Septiembre de 19 a las 16:09
2
a = "a=b,c:d"
array = ['=',',',':'];
for(i=0; i< array.length; i++){ a= a.split(array[i]).join(); }
esto devolverá la cadena sin un carácter especial.
Respondido 09 Abr '19, 14:04
1
Encuentro que una de las principales razones por las que necesito esto es dividir las rutas de los archivos en ambos /
y \
. Es una expresión regular un poco complicada, así que la publicaré aquí como referencia:
var splitFilePath = filePath.split(/[\/\\]/);
Respondido 13 Jul 15, 17:07
1
Creo que es más fácil si especificas lo que quieres dejar, en lugar de lo que quieres eliminar.
Como si solo quisiera tener palabras en inglés, puede usar algo como esto:
text.match(/[a-z'\-]+/gi);
Ejemplos (ejecutar fragmento):
var R=[/[a-z'\-]+/gi,/[a-z'\-\s]+/gi];
var s=document.getElementById('s');
for(var i=0;i<R.length;i++)
{
var o=document.createElement('option');
o.innerText=R[i]+'';
o.value=i;
s.appendChild(o);
}
var t=document.getElementById('t');
var r=document.getElementById('r');
s.onchange=function()
{
r.innerHTML='';
var x=s.value;
if((x>=0)&&(x<R.length))
x=t.value.match(R[x]);
for(i=0;i<x.length;i++)
{
var li=document.createElement('li');
li.innerText=x[i];
r.appendChild(li);
}
}
<textarea id="t" style="width:70%;height:12em">even, test; spider-man
But saying o'er what I have said before:
My child is yet a stranger in the world;
She hath not seen the change of fourteen years,
Let two more summers wither in their pride,
Ere we may think her ripe to be a bride.
—Shakespeare, William. The Tragedy of Romeo and Juliet</textarea>
<p><select id="s">
<option selected>Select a regular expression</option>
<!-- option value="1">/[a-z'\-]+/gi</option>
<option value="2">/[a-z'\-\s]+/gi</option -->
</select></p>
<ol id="r" style="display:block;width:auto;border:1px inner;overflow:scroll;height:8em;max-height:10em;"></ol>
</div>
Respondido 25 ago 15, 14:08
1
A partir de la solución @ stephen-sweriduk (¡eso fue lo más interesante para mí!), Lo modifiqué ligeramente para que sea más genérico y reutilizable:
/**
* Adapted from: http://stackoverflow.com/questions/650022/how-do-i-split-a-string-with-multiple-separators-in-javascript
*/
var StringUtils = {
/**
* Flatten a list of strings
* http://rosettacode.org/wiki/Flatten_a_list
*/
flatten : function(arr) {
var self=this;
return arr.reduce(function(acc, val) {
return acc.concat(val.constructor === Array ? self.flatten(val) : val);
},[]);
},
/**
* Recursively Traverse a list and apply a function to each item
* @param list array
* @param expression Expression to use in func
* @param func function of (item,expression) to apply expression to item
*
*/
traverseListFunc : function(list, expression, index, func) {
var self=this;
if(list[index]) {
if((list.constructor !== String) && (list[index].constructor === String))
(list[index] != func(list[index], expression)) ? list[index] = func(list[index], expression) : null;
(list[index].constructor === Array) ? self.traverseListFunc(list[index], expression, 0, func) : null;
(list.constructor === Array) ? self.traverseListFunc(list, expression, index+1, func) : null;
}
},
/**
* Recursively map function to string
* @param string
* @param expression Expression to apply to func
* @param function of (item, expressions[i])
*/
mapFuncToString : function(string, expressions, func) {
var self=this;
var list = [string];
for(var i=0, len=expressions.length; i<len; i++) {
self.traverseListFunc(list, expressions[i], 0, func);
}
return self.flatten(list);
},
/**
* Split a string
* @param splitters Array of characters to apply the split
*/
splitString : function(string, splitters) {
return this.mapFuncToString(string, splitters, function(item, expression) {
return item.split(expression);
})
},
}
y luego
var stringToSplit = "people and_other/things";
var splitList = [" ", "_", "/"];
var splittedString=StringUtils.splitString(stringToSplit, splitList);
console.log(splitList, stringToSplit, splittedString);
que devuelve como el original:
[ ' ', '_', '/' ] 'people and_other/things' [ 'people', 'and', 'other', 'things' ]
Respondido 11 Feb 16, 09:02
1
No conozco el rendimiento de RegEx, pero aquí hay otra alternativa para RegEx que aprovecha el HashSet nativo y funciona en la complejidad O (max (str.length, delimeter.length)) en su lugar:
var multiSplit = function(str,delimiter){
if (!(delimiter instanceof Array))
return str.split(delimiter);
if (!delimiter || delimiter.length == 0)
return [str];
var hashSet = new Set(delimiter);
if (hashSet.has(""))
return str.split("");
var lastIndex = 0;
var result = [];
for(var i = 0;i<str.length;i++){
if (hashSet.has(str[i])){
result.push(str.substring(lastIndex,i));
lastIndex = i+1;
}
}
result.push(str.substring(lastIndex));
return result;
}
multiSplit('1,2,3.4.5.6 7 8 9',[',','.',' ']);
// Output: ["1", "2", "3", "4", "5", "6", "7", "8", "9"]
multiSplit('1,2,3.4.5.6 7 8 9',' ');
// Output: ["1,2,3.4.5.6", "7", "8", "9"]
Respondido 25 Oct 16, 12:10
Sí, ¿qué tal si realmente pruebas algo que escribes?jsperf.com/slice-vs-personalizado Esto muestra que su código es en realidad 10 veces más lento en este ejemplo. ¿Qué le dio la idea de que usar 2 tiempos de corte, 2 tiempos concat, 1 tiempo dividido, 1 turno de tiempo y sin caché de longitud es amigable con el rendimiento? - Petar
Actualicé el código, ahora solo hay una cantidad mínima de corte sin cambio, división, etc.- orhun alp oral
1
Una forma fácil de hacer esto es procesar cada carácter de la cadena con cada delimitador y construir una matriz de divisiones:
splix = function ()
{
u = [].slice.call(arguments); v = u.slice(1); u = u[0]; w = [u]; x = 0;
for (i = 0; i < u.length; ++i)
{
for (j = 0; j < v.length; ++j)
{
if (u.slice(i, i + v[j].length) == v[j])
{
y = w[x].split(v[j]); w[x] = y[0]; w[++x] = y[1];
};
};
};
return w;
};
console.logg = function ()
{
document.body.innerHTML += "<br>" + [].slice.call(arguments).join();
}
splix = function() {
u = [].slice.call(arguments);
v = u.slice(1);
u = u[0];
w = [u];
x = 0;
console.logg("Processing: <code>" + JSON.stringify(w) + "</code>");
for (i = 0; i < u.length; ++i) {
for (j = 0; j < v.length; ++j) {
console.logg("Processing: <code>[\x22" + u.slice(i, i + v[j].length) + "\x22, \x22" + v[j] + "\x22]</code>");
if (u.slice(i, i + v[j].length) == v[j]) {
y = w[x].split(v[j]);
w[x] = y[0];
w[++x] = y[1];
console.logg("Currently processed: " + JSON.stringify(w) + "\n");
};
};
};
console.logg("Return: <code>" + JSON.stringify(w) + "</code>");
};
setTimeout(function() {
console.clear();
splix("1.23--4", ".", "--");
}, 250);
@import url("http://fonts.googleapis.com/css?family=Roboto");
body {font: 20px Roboto;}
Uso:
splix(string, delimiters...)
Ejemplo:
splix("1.23--4", ".", "--")
Devoluciones:
["1", "23", "4"]
Respondido el 20 de junio de 20 a las 10:06
1
División de URL por . Com / or .red/
url.split(/\.com\/|\.net\//)
Respondido 29 Jul 20, 16:07
0
No es la mejor manera, pero funciona para dividir con varios y diferentes separadores / delimitadores
html
<button onclick="myFunction()">Split with Multiple and Different seperators/delimiters</button>
<p id="demo"></p>
javascript
<script>
function myFunction() {
var str = "How : are | you doing : today?";
var res = str.split(' | ');
var str2 = '';
var i;
for (i = 0; i < res.length; i++) {
str2 += res[i];
if (i != res.length-1) {
str2 += ",";
}
}
var res2 = str2.split(' : ');
//you can add countless options (with or without space)
document.getElementById("demo").innerHTML = res2;
</script>
Respondido 31 ago 18, 14:08
0
Por diversión, resolví esto con reducir y filtrar. En la vida real probablemente usaría Aarons respondió aquí. Sin embargo, creo que mi versión no es totalmente ilegible o ineficiente:
[' ','_','-','.',',',':','@'].reduce(
(segs, sep) => segs.reduce(
(out, seg) => out.concat(seg.split(sep)), []),
['E-mail Address: user@domain.com, Phone Number: +1-800-555-0011']
).filter(x => x)
O en función:
function msplit(str, seps) {
return seps.reduce((segs, sep) => segs.reduce(
(out, seg) => out.concat(seg.split(sep)), []
), [str]).filter(x => x);
}
Esto dará como resultado:
['E','mail','Address','user','domain','com','0','Phone','Number','+1','800','555','0011']
Sin el filtro al final, obtendría cadenas vacías en la matriz donde dos separadores diferentes están uno al lado del otro.
Respondido el 18 de Septiembre de 20 a las 22:09
0
Me encontré con esta pregunta mientras buscaba un reemplazo para la función C # string.Split () que divide una cadena usando los caracteres en su argumento.
En JavaScript, puede hacer lo mismo usando map y reduce para iterar sobre los caracteres de división y los valores intermedios:
let splitters = [",", ":", ";"]; // or ",:;".split("");
let start= "a,b;c:d";
let values = splitters.reduce((old, c) => old.map(v => v.split(c)).flat(), [start]);
// values is ["a", "b", "c", "d"]
flat () se usa para aplanar los resultados intermedios, por lo que cada iteración funciona en una lista de cadenas sin matrices anidadas. Cada iteración se aplica dividir a todos los valores en el antiguo y luego devuelve la lista de resultados intermedios para dividir por el siguiente valor en divisores. reduce () se inicializa con una matriz que contiene el valor de cadena inicial.
Respondido el 09 de enero de 21 a las 11:01
-2
Yo uso regexp:
str = 'Write a program that extracts from a given text all palindromes, e.g. "ABBA", "lamal", "exe".';
var strNew = str.match(/\w+/g);
// Output: ["Write", "a", "program", "that", "extracts", "from", "a", "given", "text", "all", "palindromes", "e", "g", "ABBA", "lamal", "exe"]
Respondido 02 Abr '15, 06:04
Esto no hace nada con palíndromos, solo palabras. - nathan tuggy
No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas javascript regex split or haz tu propia pregunta.
Tuve este problema al intentar dividir las rutas de los archivos que se construyeron con nodejs en Windows. A veces había barras diagonales "/" y traseras "\" en la misma ruta. - Fuhrmanator