2012-03-01 10 views
5

¿Por qué javascript reemplaza la función de cadena?Javascript string regex /.*/gm no captura todas las líneas a la vez

"aaa\nbbb\nccc".replace(/.*/gm, ".") 
// result = "..\n..\n.." but expected was: ".\n.\n." 

"aaa\nbbb\nccc".replace(/^.*/gm, ".") 
// result = ".\n.\n." -> OK!!! 

"aaa\nbbb\nccc".replace(/.*$/gm, ".") 
// result = "..\n..\n.." but expected was: ".\n.\n." 

¿Qué estoy haciendo mal?

Respuesta

6

permítanme abordar aquellos en orden inverso:

Lo que estoy haciendo mal?

Quiere usar +, no *. * significa cero o más coincidencias, lo cual no tiene sentido aquí. + significa una o más coincidencias. Por lo tanto:

"aaa\nbbb\nccc".replace(/.+/g, ".") 
// ".\n.\n." 

También tenga en cuenta que si usted no está usando ^ o $ (el primer ejemplo), no es necesario el modificador m (pero que no era el problema con lo que estaba haciendo). Y no necesita ^ o $ porque .doesn't match newlines (algo que no sabía antes de responder a esta pregunta).

¿Por qué javascript replace string function hace esto?

No tengo ninguna idea terrenal y espero que alguien más lo haga.

Nuevamente, al usar * dice cero o más coincidencias. Por lo tanto, coincide con todos los personajes relevantes, reemplazándolos por el primer punto; luego coincide con cero caracteres, reemplazándolos con un punto. Resultado: dos puntos.

Prueba:

Live copy | Live source

"aaa\nbbb\nccc".replace(/.*/g, function(m) { 
    console.log("m = '" + m + "'"); 
}); 

Salidas:

m = 'aaa' 
m = '' 
m = 'bbb' 
m = '' 
m = 'ccc' 
m = ''
+0

Me encanta la "fuente en vivo". Gran explicación –

+0

Gran explicación, esto merece + a_lot. No sabía que '.' tampoco coincidía con las líneas nuevas. –

3

Tenga una mirada en esta instrucción:

"aaa\nbbb\nccc".replace(/(.*)/gm, ".$1.") 

produce:

".aaa... 
.bbb... 
.ccc..." 

.* partidos aaa y lo reemplaza por .aaa., luego coincide con una cadena vacía y se vuelve a cambiar por ...

El mismo comportamiento cuando se reemplaza por .*.

Como se ha dicho T. J.Crowder, utilice éste en su lugar: .+

"aaa\nbbb\nccc".replace(/.+/g, ".") 
1

Sorprendentemente, se espera que el comportamiento. Una cadena vacía satisface la expresión regular .*:

/.*/.test(""); 
// true 

/.*/.exec(""); 
// [""] 

Para entender lo que está pasando, observe la salida:

"aaa\nbbb\nccc".match(/.*/g); 
// ["aaa", "", "bbb", "", "ccc", ""] 
// m flag dropped because^and $ are not used 

Teniendo en cuenta que . no coincide con \n, el partido de reemplazo se realiza de la siguiente manera:

  • .* partidos aaa
  • debido g bandera, la cadena después de aaa se busca en un partido
    • .* partidos "" - una cadena de longitud cero después aaa y antes \n
    • .* no coincide \n
    • .* partidos bbb
    • .* coincide con "" - una cadena de longitud cero después de bbb y antes de \n

Y así sucesivamente. Simplemente use .+ para evitar que coincidan cadenas vacías.

+0

". * No coincide \ n". Bueno saber. –

Cuestiones relacionadas