Los cuantificadores greedy, reluctant y possessive en expresiones regulares
Escrito por
el .
java
planeta-codigo
programacion
Enlace permanente
Comentarios
En el mundo de las expresiones regulares hay tres tipos de cuantificadores que varían el comportamiento según el número caracteres que toman para encontrar ocurrencias. Son greedy o avaricioso, reluctant o reacio y possessive o posesivo. Cada cuantificador tiene una expresión en una expresión regular. La opción más habitual es el cuantificador greedy, añadiendo una ? se convierte en reluctant y añadiendo un + se convierte en possessive.
Greedy Reluctant Possessive Significado X? X?? X?+ X, uno o ninguno X* X*? X*+ X, cero o mas X+ X+? X++ X, uno o más X{n} X{n}? X{n}+ X, exactamente n veces X{n,} X{n,}? X{n,}+ X, al menos n veces X{n,m} X{n,m}? X{n,m}+ X, al menos n veces pero no mas de m
Aparentemente cada uno de los cuantificadores realiza lo mismo, sin embargo, hay diferencias en su comportamiento al hacer emparejamientos entre los elementos de la expresión regular y la cadena en la que se está aplicando.
- Greedy o avaricioso: este cuantificador intenta obtener el emparejamiento más largo que pueda, tantos caracteres como pueda, si el emparejamiento no es válido elimina un caracter de la cadena que se está comprobando y lo intenta de nuevo.
- Reluctant, reacio o vago: funciona al contrario que el cuantificador greedy, intentando inicialmente ningún caracter, tan pocos caracteres como pueda, si el emparejamiento no es válido añade un caracter de la cadena que se está comprobando y lo intenta de nuevo.
- Possessive o posesivo: funciona igual que greedy salvo que si el emparejamiento no es válido no elimina un caracter de la cadena que se está comprobando y finaliza la comprobación.
|
|
|
|
En el primer ejemplo del cuantificador greedy se usa .* para encontrar cualquier cosa, cero o más veces, seguido de las letras f o o. Dado que el cuantificador de la expresión la expresión .* es avaricioso primero consume toda la cadena. En este punto, no hay coincidencia dado que las tres últimas letras (f o o) han sido consumidas. De modo que se busca con una letra menos sucesivamente hasta que la la ocurrencia más a la derecha de foo ha sido regurgitada, en este punto hay coincidencia y la búsqueda finaliza.
En el segundo ejemplo, sin embargo, el cuantificador es reacio o vago de modo que empieza consumiendo nada. Dado que foo no aparece en el inicio de la cadena es forzado a tomar la primera letra x con la que se encuentra la primera coincidencia entre 0 y 4. Se siguen encontrando coincidencias hasta que la cadena de entrada ha sido consumida. Encuentra otra coincidencia en 4 y 13.
En el tercer caso se se hayan coincidencias ya que el cuantificador es posesivo. En este caso, la cadena completa es consumida por .*+ dejando nada que satisfaga el patrón foo al final de la expresión. Dado que no vuelve hacia atrás tiene mejor rendimiento que el cuantificador greedy en los casos que se quiera encontrar una coincidencia completa en algo.
El código fuente completo del ejemplo puedes descargarlo del repositorio de ejemplos de Blog Bitix alojado en GitHub y probarlo en tu equipo ejecutando siguiente comando:./gradlew run
- Extraer elementos de una cadena con una expresión regular
- Referencias a grupos de captura en expresiones regulares y reemplazos
- Ofuscar datos sensibles en las trazas con Log4j
- Lookahead y lookbehind en expresiones regulares con Java
- Regular Expression Quantifiers
- Greedy vs. Reluctant vs. Possessive Quantifiers
- Regex Quantifier Tutorial: Greedy, Lazy, Possessive