test - ¿Por qué JavaScript regex.exec() no siempre devuelve el mismo valor?
string to regex javascript (3)
Múltiples partidos
Si su expresión regular necesita la bandera g
(coincidencia global), deberá restablecer el índice (posición de la última coincidencia) utilizando la propiedad lastIndex
.
reg.lastIndex = 0;
Esto se debe al hecho de que exec()
se detendrá en cada aparición para que pueda ejecutar nuevamente en la parte restante . Este comportamiento también existe con test()
):
Si su expresión regular usa el indicador "g", puede usar el método exec varias veces para buscar coincidencias sucesivas en la misma cadena. Cuando lo hace, la búsqueda comienza en la subcadena de str especificada por la propiedad lastIndex de la expresión regular (la prueba también avanzará la propiedad lastIndex)
Partido simple
Cuando solo hay una coincidencia posible, simplemente puede volver a escribir regex omitiendo el indicador g
, ya que el índice se restablecerá automáticamente a 0
.
Esta pregunta ya tiene una respuesta aquí:
En la consola de Chrome o Firebug:
reg = /ab/g
str = "abc"
reg.exec(str)
==> ["ab"]
reg.exec(str)
==> null
reg.exec(str)
==> ["ab"]
reg.exec(str)
==> null
¿Es el ejecutivo de alguna manera con estado y depende de lo que devolvió la vez anterior? ¿O es solo un error? No puedo hacer que suceda todo el tiempo. Por ejemplo, si ''str'' anterior fuera "abc abc", no sucede.
De los documentos de MDN :
Si su expresión regular usa el indicador "g", puede usar el método exec varias veces para buscar coincidencias sucesivas en la misma cadena. Cuando lo hace, la búsqueda comienza en la subcadena de str especificada por la propiedad lastIndex de la expresión regular (la prueba también avanzará la propiedad lastIndex).
Como está utilizando el indicador g
, el exec
continúa desde la última cadena coincidente hasta que llega al final (devuelve null
) y luego comienza de nuevo.
Personalmente, prefiero ir al revés con str.match(reg)
Un objeto RegExp
JavaScript es con estado.
Cuando la expresión regular es global, si llama a un método el mismo objeto regex, comenzará desde el índice más allá del final de la última coincidencia.
Cuando no se encuentran más coincidencias, el índice se restablece a 0
automáticamente.
Para restablecerlo manualmente, configure la propiedad lastIndex
.
reg.lastIndex = 0;
Esta puede ser una característica muy útil. Puede iniciar la evaluación en cualquier punto de la cadena, si lo desea, o si está en un bucle, puede detenerlo después de un número deseado de coincidencias.
Aquí hay una demostración de un enfoque típico para usar la expresión regular en un bucle. Aprovecha el hecho de que el exec
devuelve null
cuando no hay más coincidencias al realizar la asignación como la condición de bucle.
var re = /foo_(/d+)/g,
str = "text foo_123 more text foo_456 foo_789 end text",
match,
results = [];
while (match = re.exec(str))
results.push(+match[1]);
DEMO: http://jsfiddle.net/pPW8Y/
Si no te gusta la ubicación de la tarea, el ciclo se puede volver a trabajar, así por ejemplo ...
var re = /foo_(/d+)/g,
str = "text foo_123 more text foo_456 foo_789 end text",
match,
results = [];
do {
match = re.exec(str);
if (match)
results.push(+match[1]);
} while (match);