backreferences regex optional capturing-group

backreferences - Regex grupo de captura opcional?



numeric reference regex (3)

Después de horas de búsqueda decidí hacer esta pregunta. ¿Por qué esta expresión regular: ^(dog).+?(cat)? no funciona como creo que debería funcionar (capturar el primer perro y el gato si hay alguno)? ¿Que me estoy perdiendo aqui?

dog, cat dog, dog, cat dog, dog, dog


La extensión de @figha se puede extender un poco más, para no realizar la segunda captura innecesaria.

Use ?: Para hacer que una parte entre corchetes de una expresión regular no se pueda capturar. ¿Entonces la expresión regular se convierte en: ^(dog)(?:.+(cat))?

Una vez más, aquí está la demo extendida y la prueba de expresiones regulares .


La razón por la que no obtiene un cat opcional después de un calificado de mala gana .+? es que es opcional y no está anclado: el motor no está obligado a hacer esa coincidencia, porque puede tratar legalmente al cat como la "cola" de .+? secuencia.

Si anclas al gato al final de la cadena, es decir, si usas ^(dog).+?(cat)?$ , Obtendrías una coincidencia, aunque:

Pattern p = Pattern.compile("^(dog).+?(cat)?$"); for (String s : new String[] {"dog, cat", "dog, dog, cat", "dog, dog, dog"}) { Matcher m = p.matcher(s); if (m.find()) { System.out.println(m.group(1)+" "+m.group(2)); } }

Esto imprime ( demo 1 )

dog cat dog cat dog null

¿Sabes cómo lidiar con eso en caso de que haya algo después de un gato?

Puedes lidiar con eso construyendo una expresión más complicada que coincida con cualquier cosa, excepto cat , como esto:

^(dog)(?:[^c]|c[^a]|ca[^t])+(cat)?

Ahora el cat podría pasar en cualquier parte de la cadena sin un ancla ( demo 2 ).


La respuesta de @ dasblinkenlight es genial, pero aquí hay una expresión regular que mejora la segunda parte de la misma, cuando él / ella pregunta

¿Sabes cómo lidiar con eso en caso de que haya algo después de un gato?

La expresión regular ^(dog)(.+(cat))? requerirías que capturaras el grupo no. 3 en lugar de 2 para obtener el gato opcional, pero funciona igual de bien sin el engaño char-by-char.

Y aquí está la demostración (que, de nuevo, está bifurcada de la demostración de @ dasblinkenlight que me permitió jugar y encontrar esta solución, ¡gracias de nuevo!)