Reemplace todos los caracteres no alfanuméricos, nuevas líneas y múltiples espacios en blanco con un espacio

136

Estoy buscando una solución ordenada de RegEx para reemplazar

  • Todos los caracteres no alfanuméricos
  • Todas las nuevas líneas
  • Todas las instancias múltiples de espacio en blanco

Con un solo espacio


Para aquellos que juegan en casa ( lo siguiente funciona )

text.replace(/[^a-z0-9]/gmi, " ").replace(/\s+/g, " ");

Mi pensamiento es que RegEx es probablemente lo suficientemente poderoso como para lograr esto en una sola declaración. Los componentes que creo que necesito son:

  • [^a-z0-9] - para eliminar caracteres no alfanuméricos
  • \s+ - coincide con cualquier colección de espacios
  • \r?\n|\r - coincide con toda la nueva línea
  • /gmi - global, multilínea, sin distinción entre mayúsculas y minúsculas

Sin embargo, parece que no puedo diseñar la expresión regular de la manera correcta ( lo siguiente no funciona )

text.replace(/[^a-z0-9]|\s+|\r?\n|\r/gmi, " ");


Entrada

234&^%,Me,2 2013 1080p x264 5 1 BluRay
S01(*&asd 05
S1E5
1x05
1x5


Salida deseada

234 Me 2 2013 1080p x264 5 1 BluRay S01 asd 05 S1E5 1x05 1x5
El general
fuente
¿Cómo exactamente su intento no funciona? Que sale mal
Puntiagudo

Respuestas:

235

Tenga en cuenta que eso \W deja el guión bajo . Un equivalente corto para [^a-zA-Z0-9]sería[\W_]

text.replace(/[\W_]+/g," ");

\Wes la negación de la taquigrafía \w para [A-Za-z0-9_]caracteres de palabras (incluido el guión bajo)

Ejemplo en regex101.com

Jonny 5
fuente
Compruébalo y pruébalo, todavía no tienes mucha experiencia en js-regex: p Feliz de que te guste
Jonny 5
66
Tenga en cuenta que \Wtambién reconocerá los caracteres no latinos como caracteres sin palabras.
Tyblitz
1
Marqué esta respuesta correcta después de todos estos años, porque miré hacia atrás y lo aceptado no excluyó los guiones bajos
TheGeneral
143

Jonny 5 me ganó. Iba a sugerir usar el \W+sin el \scomo en text.replace(/\W+/g, " "). Esto cubre el espacio en blanco también.

T-CatSan
fuente
¡Gracias @ T-CatSan por señalar eso! Subido, y Saruman, eres libre de cambiar la mejor respuesta a lo que sea :-) Pero debería ser \W+, no [W+]Bueno, ¡feliz año nuevo a todos!
Jonny 5
Gracias, @ Jonny5! He hecho el cambio que sugeriste. Había probado con los soportes antes y ahora veo que funciona sin ellos. Feliz Año Nuevo para ti también.
T-CatSan
1
hey @ T-CatSan, ¿hay alguna forma de agregar excepciones? Quiero mantener personajes &y -. ¿Algun consejo?
Renato Gama
1
Hice el siguiente cambio / (\ W +) | (_) / g para ignorar _ también. Pero me pregunto por qué no se ignora en el primer modelo y si mi expresión regular es la eficiente.
Sridhar Gudimela
14

Como la [^a-z0-9]clase de caracteres contiene todo lo que no es alnum, ¡también contiene caracteres blancos!

 text.replace(/[^a-z0-9]+/gi, " ");
Casimir et Hippolyte
fuente
6

Bueno, creo que solo necesitas agregar un cuantificador a cada patrón. También lo de retorno de carro es un poco divertido:

text.replace(/[^a-z0-9]+|\s+/gmi, " ");

editar La \scosa coincide \ry \ntambién.

Puntiagudo
fuente
Sí, había algunas tonterías de Tom extraídas de otras respuestas sobre el tema, sin embargo, eso funciona muy bien, ¡gracias!
TheGeneral
2

A vi una publicación diferente que también tenía marcas diacríticas, lo cual es genial

s.replace(/[^a-zA-Z0-9À-ž\s]/g, "")

Dmitri R117
fuente
2

Este es un viejo post mío, las respuestas aceptadas son buenas en su mayor parte. Sin embargo, decidí comparar cada solución y otra obvia (solo por diversión). Me preguntaba si había una diferencia entre los patrones de expresiones regulares en diferentes navegadores con cadenas de diferentes tamaños.

Así que básicamente usé jsPerf en

  • Pruebas en Chrome 65.0.3325 / Windows 10 0.0.0
  • Prueba en Edge 16.16299.0 / Windows 10 0.0.0

Los patrones de expresiones regulares que probé fueron

  • /[\W_]+/g
  • /[^a-z0-9]+/gi
  • /[^a-zA-Z0-9]+/g

Los cargué con una longitud de cadena de caracteres aleatorios

  • longitud 5000
  • longitud 1000
  • longitud 200

Ejemplo de JavaScript que utilicé var newstr = str.replace(/[\W_]+/g," ");

Cada ejecución constaba de 50 o más muestras en cada expresión regular, y las ejecuto 5 veces en cada navegador.

¡Vamos a competir con nuestros caballos!

Resultados

                                Chrome                  Edge
Chars   Pattern                 Ops/Sec     Deviation   Op/Sec      Deviation
------------------------------------------------------------------------
5,000   /[\W_]+/g                19,977.80  1.09         10,820.40  1.32
5,000   /[^a-z0-9]+/gi           19,901.60  1.49         10,902.00  1.20
5,000   /[^a-zA-Z0-9]+/g         19,559.40  1.96         10,916.80  1.13
------------------------------------------------------------------------
1,000   /[\W_]+/g                96,239.00  1.65         52,358.80  1.41
1,000   /[^a-z0-9]+/gi           97,584.40  1.18         52,105.00  1.60
1,000   /[^a-zA-Z0-9]+/g         96,965.80  1.10         51,864.60  1.76
------------------------------------------------------------------------
  200   /[\W_]+/g               480,318.60  1.70        261,030.40  1.80
  200   /[^a-z0-9]+/gi          476,177.80  2.01        261,751.60  1.96
  200   /[^a-zA-Z0-9]+/g        486,423.00  0.80        258,774.20  2.15

A decir verdad, Regex en ambos navegadores (teniendo en cuenta la desviación) era casi indistinguible, sin embargo, creo que si se ejecuta esto aún más veces, los resultados serían un poco más claros (pero no mucho).

Escala teórica para 1 personaje

                            Chrome                        Edge
Chars   Pattern             Ops/Sec     Scaled            Op/Sec    Scaled
------------------------------------------------------------------------
5,000   /[\W_]+/g            19,977.80  99,889,000       10,820.40  54,102,000
5,000   /[^a-z0-9]+/gi       19,901.60  99,508,000       10,902.00  54,510,000
5,000   /[^a-zA-Z0-9]+/g     19,559.40  97,797,000       10,916.80  54,584,000
------------------------------------------------------------------------

1,000   /[\W_]+/g            96,239.00  96,239,000       52,358.80  52,358,800
1,000   /[^a-z0-9]+/gi       97,584.40  97,584,400       52,105.00  52,105,000
1,000   /[^a-zA-Z0-9]+/g     96,965.80  96,965,800       51,864.60  51,864,600
------------------------------------------------------------------------

  200   /[\W_]+/g           480,318.60  96,063,720      261,030.40  52,206,080
  200   /[^a-z0-9]+/gi      476,177.80  95,235,560      261,751.60  52,350,320
  200   /[^a-zA-Z0-9]+/g    486,423.00  97,284,600      258,774.20  51,754,840

No tomaría demasiado en estos resultados, ya que esta no es realmente una diferencia significativa, todo lo que realmente podemos decir es que el borde es más lento: o. Además que estaba súper aburrido.

De todos modos, puede ejecutar el punto de referencia para usted.

Jsperf Benchmark aquí

El general
fuente
0

Para reemplazar con guiones, haga lo siguiente:

text.replace(/[\W_-]/g,' ');
Gregory R.
fuente