Regex para reemplazar múltiples espacios con un solo espacio

511

Dada una cadena como:

"¡El perro tiene una cola larga y es ROJA!"

¿Qué tipo de magia jQuery o JavaScript se puede usar para mantener los espacios en un solo espacio máximo?

Objetivo:

"¡El perro tiene una cola larga y es ROJA!"
Un aprendiz
fuente
44
¿También quieres hacer coincidir los caracteres de tabulación de espacios en blanco?
Chris Farmer
@ Chris, sí, por favor, una gran pregunta ... Con todas estas respuestas diferentes, ¿cómo se supone que uno sabe cuál es la solución más eficiente?
AnApprentice
2
Todos los que están abajo tienen razón, pero esta es la expresión regular más optimizada: str.replace(/ +(?= )/g,'');no está reemplazando nada que no tenga que hacer.
Evan Carroll
2
No habrá ninguna diferencia notable en el rendimiento. Siempre puedes perfilarlo, pero dudo que valga la pena. Yo iría por lo más claro.
Draemon
@EvanCarroll: No es cierto, al menos en Firefox. Esa versión corre significativamente más lenta. Vea los resultados del perfil en mi respuesta (a continuación).
Edward Loper

Respuestas:

937

Dado que también desea cubrir pestañas, líneas nuevas, etc., simplemente reemplace \s\s+con ' ':

string = string.replace(/\s\s+/g, ' ');

Si realmente desea cubrir solo espacios (y, por lo tanto, no pestañas, líneas nuevas, etc.), hágalo:

string = string.replace(/  +/g, ' ');
BalusC
fuente
44
También debe agregar la bandera 'g' a la expresión regular.
Rafael
66
Esto no funciona cuando se necesita un espacio en blanco en lugar de una pestaña o una nueva línea. ¿Derecha? / \ s + / estaría funcionando.
Fabian
3
podría ser mejor para usted como una función comofunction removeExtraSpaces(string){ return string.replace(/\s{2,}/g, ' ');}
Math chiller
55
@Ethan: JS tiene una función incorporada para que: trim(). Es más rápido que la expresión regular. Podrías simplemente hacer string.trim().replace(/\s\s+/g, ' ');o string.replace(/\s\s+/g, ' ').trim();.
BalusC
44
/\s\s+/gy /\s{2,}/gno coinciden con los espacios en blanco a menos que haya al menos dos adyacentes entre sí, por ejemplo, coincidirá con \ t \ t pero no con \ t \. string.replace(/\s+/g, ' ')coincidirá con todas las subcadenas de caracteres de espacios en blanco simples y múltiples y las reemplazará con un solo espacio.
remyActual
159

Como parece estar interesado en el rendimiento, lo perfilé con firebug. Aquí están los resultados que obtuve:

str.replace( /  +/g, ' ' )       ->  380ms
str.replace( /\s\s+/g, ' ' )     ->  390ms
str.replace( / {2,}/g, ' ' )     ->  470ms
str.replace( / +/g, ' ' )        ->  790ms
str.replace( / +(?= )/g, ' ')    -> 3250ms

Esto está en Firefox, ejecutando reemplazos de cadena de 100k.

Te animo a que hagas tus propias pruebas de perfil con firebug, si crees que el rendimiento es un problema. Los humanos son notoriamente malos al predecir dónde se encuentran los cuellos de botella en sus programas.

(Además, tenga en cuenta que la barra de herramientas del desarrollador de IE 8 también tiene un generador de perfiles incorporado; puede valer la pena comprobar cómo es el rendimiento en IE)

Edward Loper
fuente
55
jsperf.com/removing-multiple-spaces ¡ Adelante y JSPerf! El ultimo metodo; ( / +(?= )/g, ' ');falla en IE9, deja espacios dobles: "Foo Bar Baz".replace(/ +(?= )/g, ' ');->"Foo Bar Baz"
Nenotlep
cómo hay mucha diferencia bw 1 y segunda línea
Vivek Panday
@VivekPanday: me imagino que esto se debe a que la segunda línea solo reemplaza las ocurrencias de espacios dobles con un solo espacio, mientras que la primera también reemplaza cualquier espacio con un espacio. Si esto es tiempo ahorrado durante la búsqueda o el reemplazo real, no lo sé.
Maloric
Esto no elimina los espacios en blanco iniciales y finales. Para eso mira esta respuesta .
Ethan
Editado a pedido disminuyendo la velocidad. Los comentarios de Vivek y Maloric se refieren a líneas con 380 ms y 790 ms.
Skippy le Grand Gourou
43
var str = "The      dog        has a long tail,      and it is RED!";
str = str.replace(/ {2,}/g,' ');

EDITAR: Si desea reemplazar todo tipo de caracteres de espacio en blanco, la forma más eficiente sería así:

str = str.replace(/\s{2,}/g,' ');
camarero
fuente
Es curioso que tu cadena de prueba ni siquiera tenga dos espacios.
Josh Stodola
acabo de dar cuenta que ya tenía lo que recientemente ocurrió con, 1 :)
meder Omuraliev
2
Por alguna razón, esto no funciona ... Una gran cantidad de "& nbsp;" están apareciendo ... Probablemente debido a CKEDITOR ...
AnApprentice
K resulta que el texto de JQUERY () estaba arruinando las cosas. arreglado - gracias a todos!
AnApprentice
16

Esta es una solución, aunque apuntará a todos los caracteres de espacio:

"The      dog        has a long tail,      and it is RED!".replace(/\s\s+/g, ' ')

"The dog has a long tail, and it is RED!"

Editar : Esto probablemente sea mejor ya que apunta a un espacio seguido de 1 o más espacios:

"The      dog        has a long tail,      and it is RED!".replace(/  +/g, ' ')

"The dog has a long tail, and it is RED!"

Método alternativo:

"The      dog        has a long tail,      and it is RED!".replace(/ {2,}/g, ' ')
"The dog has a long tail, and it is RED!"

No lo utilicé /\s+/solo, ya que reemplaza los espacios que abarcan 1 carácter varias veces y podría ser menos eficiente ya que apunta más de lo necesario.

No probé a fondo ninguno de estos, así que si hay errores.

Además, si va a hacer un reemplazo de cadena, recuerde reasignar la variable / propiedad a su propio reemplazo, por ejemplo:

var string = 'foo'
string = string.replace('foo', '')

Usando jQuery.prototype.text:

var el = $('span:eq(0)');
el.text( el.text().replace(/\d+/, '') )
meder omuraliev
fuente
1
El primero no tiene sentido, \ s \ s + significa, an \ s seguido de uno o más \ s +, que se puede reducir a un solo \ s +, el segundo ejemplo es más preciso porque solo queremos reemplazar los espacios dobles, no Newlines, el tercero está más optimizado porque solo se aplica a ejemplos con más de 2 espacios. Pero str.replace (/ + (? =) / G, '') ;, solo se aplica a ejemplos con 2+ espacios pero ahorra sobrescribiendo un espacio con un paso de espacio.
Evan Carroll
44
EvanCarroll falla porque \ s \ s + es definitivamente diferente a \ s +. \ s \ s + coincidiría con '\ t \ t' o '\ t \ t \ t' pero NO con '\ t'. Y de eso se trata, no desea reemplazar cada carácter de espacio en blanco f-en.
watain
Hago. Utilizado para la búsqueda de texto completo (y visualización de fragmentos): no hay pestañas aleatorias, no separadores o cositas, por favor.
T4NK3R
13

Tengo este método, lo llamo el método Derp por falta de un nombre mejor.

while (str.indexOf("  ") !== -1) {
    str = str.replace(/  /g, " ");
}

Ejecutarlo en JSPerf da algunos resultados sorprendentes.

Nenotlep
fuente
2
Voy a estar avergonzado como el infierno si resulta que falsifiqué el caso de prueba en lugar de que sea realmente rápido: D
Nenotlep
Proporcionando un caso de prueba ... Excelente respuesta!
Oytun
2
Esto me alegró el día :-) Es curioso cómo "derping" a menudo funciona mejor que ser todo "inteligente". Sin embargo, la "división de Derp" parece haber pateado su trasero. Aún así, merece la votación.
Fred Gandt
13

Un método más robusto: se encarga de eliminar también los espacios iniciales y finales, si existen. P.ej:

// NOTE the possible initial and trailing spaces
var str = "  The dog      has a long   tail, and it     is RED!  "

str = str.replace(/^\s+|\s+$|\s+(?=\s)/g, "");

// str -> "The dog has a long tail, and it is RED !"

Su ejemplo no tenía esos espacios, pero también son un escenario muy común, y la respuesta aceptada fue solo recortarlos en espacios individuales, como: "¡El ... ROJO!", Que no es lo que normalmente necesitará.

Ethan
fuente
3
Usé este patrón en PHP y funciona. $ partes = preg_split ("/ ^ \ s + | \ s + $ | \ s + (? = \ s) /", "Avenida Tancredo Neves, 745 Piso Térreo Sala");
Bruno Ribeiro
11

Más robusto:

función trim (word)
{
    word = word.replace (/ [^ \ x21- \ x7E] + / g, ''); // cambia los caracteres que no se imprimen a espacios
    return word.replace (/ ^ \ s + | \ s + $ / g, ''); // eliminar espacios iniciales / finales
}
Chris
fuente
8

yo sugiero

string = string.replace(/ +/g," ");

por solo espacios
O

string = string.replace(/(\s)+/g,"$1");

para convertir múltiples retornos en un solo retorno también.

Leonard Meagher
fuente
6

Sé que llego tarde a la fiesta, pero descubrí una buena solución.

Aquí está:

var myStr = myStr.replace(/[ ][ ]*/g, ' ');
ToXic73
fuente
6

Aquí hay una solución alternativa si no desea usar reemplazar (reemplazar espacios en una cadena sin usar reemplazar javascript)

var str="The dog      has a long   tail, and it     is RED!";
var rule=/\s{1,}/g;
str = str.split(rule).join(" "); 
document.write(str);
imos
fuente
5

Respuesta completa sin cifrar para novatos et al.

Esto es para todos los tontos como yo que prueban los guiones escritos por algunos de ustedes que no funcionan.

Los siguientes 3 ejemplos son los pasos que tomé para eliminar caracteres especiales Y espacios adicionales en los siguientes 3 sitios web (todos los cuales funcionan perfectamente) {1. EtaVisa.com 2. EtaStatus.com 3. Tikun.com} así que sé que funcionan perfectamente.

Los hemos encadenado con más de 50 a la vez y sin problemas.

// Esto eliminó los caracteres especiales + 0-9 y solo permite letras (mayúsculas y minúsculas)

function NoDoublesPls1()
{
var str=document.getElementById("NoDoubles1");
var regex=/[^a-z]/gi;
str.value=str.value.replace(regex ,"");
}

// Esto eliminó caracteres especiales y permite solo letras (mayúsculas y minúsculas) y 0-9 Y espacios

function NoDoublesPls2()
{
var str=document.getElementById("NoDoubles2");
var regex=/[^a-z 0-9]/gi;
str.value=str.value.replace(regex ,"");
}

// Esto eliminó caracteres especiales y permite solo letras (mayúsculas y minúsculas) y 0-9 Y espacios // El .replace (/ \ s \ s + / g, "") al final elimina espacios excesivos // cuando I utilizaba comillas simples, no funcionó.

function NoDoublesPls3()
{    var str=document.getElementById("NoDoubles3");
var regex=/[^a-z 0-9]/gi;
str.value=str.value.replace(regex ,"") .replace(/\s\s+/g, " ");
}

:: SIGUIENTE :: Guardar # 3 como a .js// Llamé al mío NoDoubles.js

:: SIGUIENTE :: Incluya su JS en su página

 <script language="JavaScript" src="js/NoDoubles.js"></script>

Incluya esto en su campo de formulario :: como

<INPUT type="text" name="Name"
     onKeyUp="NoDoublesPls3()" onKeyDown="NoDoublesPls3()" id="NoDoubles3"/>

Para que se vea así

<INPUT type="text" name="Name" onKeyUp="NoDoublesPls3()" onKeyDown="NoDoublesPls3()" id="NoDoubles3"/>

Esto eliminará caracteres especiales, permitirá espacios individuales y eliminará espacios adicionales.

PatFoster
fuente
¿Que esta pasando aqui? El formato se ve muy, muy roto.
Nenotlep
4

También una posibilidad:

str.replace( /\s+/g, ' ' )
rfunduk
fuente
1
var string = "The dog      has a long   tail, and it     is RED!";
var replaced = string.replace(/ +/g, " ");

O si también quieres reemplazar pestañas:

var replaced = string.replace(/\s+/g, " ");
Brian Campbell
fuente
1
el uso de + parece más limpio, pero también reemplazará espacios individuales con espacios individuales, un poco redundantes y no estoy seguro, pero puede crear problemas de rendimiento con un texto mucho más largo.
ahmetunal
Tiendo a usar la solución más corta y simple que funcionará, y solo me preocupo por ese tipo de optimización si sé que necesito hacer coincidir una cadena muy grande, y en ese momento mediré diferentes soluciones para ver cuál se más rápido. Puede ser difícil predecir de antemano lo que será más rápido sin pruebas; por ejemplo, en los intérpretes de JavaScript, algunas expresiones regulares complicadas harán que cambie de una implementación compilada JIT rápida a una de interpretación lenta.
Brian Campbell
1

Jquery tiene la función trim () que básicamente convierte algo así como "FOo Bar" en "FOo Bar".

var string = "  My     String with  Multiple lines    ";
string.trim(); // output "My String with Multiple lines"

Es mucho más útil porque elimina automáticamente los espacios vacíos al principio y al final de la cadena también. No se necesita expresión regular.

Eryk Wróbel
fuente
3
Como dijiste, trim () elimina los espacios vacíos al principio y al final de la cadena, pero no en el medio de la cadena, por lo tanto, no funciona en este caso, la salida sería "Mi cadena con múltiples líneas". api.jquery.com/jQuery.trim
egvaldes
1

este reemplazo no se usa, string = string.split (/ \ W + /);

Lin
fuente
0
var myregexp = new RegExp(/ {2,}/g);

str = str.replace(myregexp,' ');
ahmetunal
fuente
0

Podemos usar la siguiente expresión regular explicada con la ayuda del comando del sistema sed. La expresión regular similar se puede utilizar en otros idiomas y plataformas.

Agregue el texto en algún archivo, digamos prueba

manjeet-laptop:Desktop manjeet$ cat test
"The dog      has a long   tail, and it     is RED!"

Podemos usar la siguiente expresión regular para reemplazar todos los espacios en blanco con un solo espacio

manjeet-laptop:Desktop manjeet$ sed 's/ \{1,\}/ /g' test
"The dog has a long tail, and it is RED!"

Espero que esto sirva para el propósito

minhas23
fuente
0

Intente esto para reemplazar múltiples espacios con un solo espacio.

<script type="text/javascript">
    var myStr = "The dog      has a long   tail, and it     is RED!";
    alert(myStr);  // Output 'The dog      has a long   tail, and it     is RED!'

    var newStr = myStr.replace(/  +/g, ' ');
    alert(newStr);  // Output 'The dog has a long tail, and it is RED!'
</script>

Leer más @ Reemplazar múltiples espacios con un solo espacio

jonathan klevin
fuente
0
var text = `xxx  df dfvdfv  df    
                     dfv`.split(/[\s,\t,\r,\n]+/).filter(x=>x).join(' ');

resultado:

"xxx df dfvdfv df dfv"
Kit de herramientas
fuente
0

Para obtener más control, puede usar la devolución de llamada de reemplazo para manejar el valor.

value = "tags:HUNT  tags:HUNT         tags:HUNT  tags:HUNT"
value.replace(new RegExp(`(?:\\s+)(?:tags)`, 'g'), $1 => ` ${$1.trim()}`)
//"tags:HUNT tags:HUNT tags:HUNT tags:HUNT"
jackotonye
fuente
0

Este script elimina cualquier espacio en blanco (múltiples espacios, pestañas, retornos, etc.) entre palabras y ajustes:

// Trims & replaces any wihtespacing to single space between words
String.prototype.clearExtraSpace = function(){
  var _trimLeft  = /^\s+/,
      _trimRight = /\s+$/,
      _multiple  = /\s+/g;

  return this.replace(_trimLeft, '').replace(_trimRight, '').replace(_multiple, ' ');
};
Oriol
fuente
0

¡'puntero del mouse táctil' .replace (/ ^ \ s + | \ s + $ | (\ s) + / g, "$ 1") debería hacer el truco!

Ruwan Epage
fuente
0

Sé que tenemos que usar regex, pero durante una entrevista, me pidieron que lo hiciera SIN USAR REGEX.

@slightlytyler me ayudó a adoptar el siguiente enfoque.

const testStr = "I   LOVE    STACKOVERFLOW   LOL";

const removeSpaces = str  => {
  const chars = str.split('');
  const nextChars = chars.reduce(
    (acc, c) => {
      if (c === ' ') {
        const lastChar = acc[acc.length - 1];
        if (lastChar === ' ') {
          return acc;
        }
      }
      return [...acc, c];
    },
    [],
  );
  const nextStr = nextChars.join('');
  return nextStr
};

console.log(removeSpaces(testStr));

xSachinx
fuente
considere: console.log (testStr.split ("") .filter (s => s.length) .join (""))
dpjanes