Lookahead y lookbehind en expresiones regulares con Java
Escrito por
el .
java
planeta-codigo
programacion
Enlace permanente
Comentarios
Las expresiones regulares son un gran invento y muy útil para comprobar que una cadena cumple el patrón definido en la expresión regular, hay coincidencias en partes de la cadena y para reemplazar coincidencias. Son muy potentes para realizar estas tareas pero al mismo tiempo pueden volverse en cierta medida complicadas.
Una de las funcionalidades que soportan las cadenas es búsqueda hacia delante o lookahead y búsqueda hacia atrás o lookbehind. La primera permite examinar los siguientes caracteres de la cadena analizada y la segunda los caracteres pasados.
Hay diferentes formas de lookahead, en Java la construcción que permite hacer lookahead es (?=X) donde X es la expresión siguiente, se puede negar la expresión en el caso de querer que no se cumpla X con (?!X). También existe lookbehind con la construcción (?<=X) para negar que no se cumpla X se ha de emplear (?<!X), como su nombre sugiere en vez de mirar hacia adelante mira hacia atrás en los caracteres ya analizados.
Una aplicación práctica en la que usar lookahead es para ocultar los números de una tarjeta de crédito, una cuenta bancaria o un bearer token de un API REST excepto los cuatro últimos caracteres, este podría ser el caso de que esta información sea incluida en los archivos de log de una aplicación que por seguridad es recomendable ocultar. En el artículo Ofuscar datos sensibles en las trazas con Log4j comento varias formas de hacerlo.
Una tarjeta de crédito está formada por 4 grupos de 4 dígitos separados por espacios cumpliendo la expresión regular \d{4} \d{4} \d{4} \d{4} y un bearer token puede seguir la expresión regular Bearer \w+. Para ocultar la información de estas cadenas excepto los cuatro últimos caracteres hay que comprobar que los primeros cumplen el patrón añadiéndolos en un grupo de captura para su reemplazo posterior y mirar los cuatro siguientes si también lo cumplen fuera del grupo de captura. En el caso de la tarjeta de crédito se mira que la expresión cumple los primeros números de una tarjeta de crédito y le siguen los restantes, la primera parte se incluye en un grupo de captura con los paréntesis.
|
|
|
|
|
|
El resultado es el siguiente:
|
|
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