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!"

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, ' ');

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)


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,' ');

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+/, '') )

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.


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á.


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
}

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.


6

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

Aquí está:

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

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);

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.


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

4

También una posibilidad:

str.replace( /\s+/g, ' ' )

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, " ");

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.


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 + /);


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

str = str.replace(myregexp,' ');

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


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


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

resultado:

"xxx df dfvdfv df dfv"

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"

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, ' ');
};

0

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


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));


considere: console.log (testStr.split ("") .filter (s => s.length) .join (""))
dpjanes
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.