javascript - regulares - Regex solo captura la última instancia del grupo de captura en un partido
expresiones regulares java (2)
Independientemente del problema, ActionScript y JavaScript siempre deben arrojar los mismos resultados, ya que ambos implementan ECMAScript (o un superconjunto de los mismos, pero para las expresiones regulares no deberían estar en desacuerdo).
Pero sí, esto estará sucediendo en cualquier idioma (o más bien cualquier sabor regex). La razón es que estás repitiendo el grupo de captura. Tomemos un ejemplo más simple: match (.)*
Contra abc
. Entonces, lo que estamos repitiendo es (.)
La primera vez que se prueba, el motor ingresa al grupo, coincide con a .
, deja el grupo y captura a
. Solo ahora el cuantificador entra en acción y lo repite todo. Entonces, ingresamos al grupo nuevamente, y coincidimos y capturamos b
. Esta captura sobrescribe la anterior, por lo tanto, /1
ahora contiene b
. Lo mismo para la tercera repetición: la captura se sobrescribirá con c
.
No sé de un sabor regex que se comporta de manera diferente, y el único que le permite acceder a todas las capturas anteriores (en lugar de simplemente sobrescribirlas) es .NET.
La solución es la única propuesta. Haga que la agrupación que necesita para la repetición no capture (esto mejorará el rendimiento, porque de todos modos no necesita toda esa captura y sobreescritura) y envuelva todo en un nuevo grupo. Sin embargo, su expresión tiene un pequeño defecto: debe incluir incluir la barra diagonal inversa en la clase de caracteres negada. De lo contrario, retroceder podría darte una coincidencia en [abc/]
. Así que aquí hay una expresión que funcionará como esperabas:
/[((?://{2}|///]|[^/]//])*)/]
Demostración de trabajo (lamentablemente, no muestra las capturas, pero muestra que da coincidencias correctas en todos los casos)
Tenga en cuenta que su expresión no permite otras secuencias de escape. En particular, un único /
, seguido de cualquier cosa menos a ]
hará que su patrón falle. Si esto no es lo que deseas, puedes usar:
/[((?://.|[^/]//])*)/]
El rendimiento puede mejorarse aún más con la técnica de "desenrollar el bucle" :
/[([^/]//]*(?://.[^/]//]*)*)/]
Tengo la siguiente expresión regular en dos idiomas diferentes que produce los mismos resultados impares (javaScript y Flash). Lo que quiero saber no es cómo solucionarlo, sino ¿por qué está ocurriendo el comportamiento?
La expresión regular:
/[(//{2}|///]|[^/]])*/]
El objetivo aquí es hacer coincidir una cuerda entre corchetes y garantizar que no me detengo en un soporte escapado.
Si tengo la entrada de texto [abcdefg]
, está [abcdefg]
correctamente, pero lo único que se devuelve como parte del grupo de captura es g
, donde como espero abcdefg
. Si cambio la expresión a /[((?://{2}|///]|[^/]])*)/]
, entonces obtengo el resultado que deseo.
Entonces, ¿por qué está sucediendo esto? ¿Esto será consistente en otros idiomas?
nota: Simplificar la expresión a /[([^/]])*/]
produce el mismo problema.
Intente incluir el *
cuantificador dentro del grupo de captura, como este:
/[((?://{2}|///]|[^/]])*)/]