Red de conocimiento informático - Conocimiento informático - Familiarizado con las expresiones regulares de Java

Familiarizado con las expresiones regulares de Java

va viene con un paquete de software que admite expresiones regulares. Este artículo presentará cómo utilizar el paquete java.util.regex.

Como estimación aproximada, excepto los usuarios ocasionales de Linux, todos los usuarios de Linux x encontrarán expresiones regulares. Las expresiones regulares son una herramienta extremadamente poderosa con gran adaptabilidad para la coincidencia y reemplazo de patrones de cadenas. En el mundo Unix, las expresiones regulares casi no tienen limitaciones y ciertamente se utilizan ampliamente.

Muchas herramientas populares de Unix, incluidas grep, awk, vi y Emacs, han implementado motores de expresiones regulares. Además, las expresiones regulares son compatibles con muchos lenguajes de secuencias de comandos ampliamente utilizados, como Python, Tcl, JavaScript y, más notablemente, Perl.

Fui hacker de Perl hace mucho tiempo y, si eres como yo, confías en tener estas potentes herramientas de procesamiento de texto a tu alcance. En los últimos años, al igual que otros desarrolladores de programas, he prestado cada vez más atención al desarrollo de Java.

Como lenguaje de desarrollo, Java tiene mucho que recomendar, pero no siempre admite expresiones regulares. Hasta hace poco, Java comenzó a admitir expresiones regulares con la ayuda de bibliotecas de terceros, pero estas bibliotecas de terceros son inconsistentes, tienen poca compatibilidad y no favorecen el mantenimiento del código. Este defecto ha sido una gran preocupación para mí al elegir Java como mi principal herramienta de desarrollo.

¡Puedes imaginar mi alegría cuando supe que la versión Java JDK 1.40 de Sun incluía java.util.regex, un paquete de expresiones regulares completamente abierto e independiente! Curiosamente, me tomó algo de tiempo desenterrar este tesoro escondido. Estoy realmente sorprendido de por qué una mejora tan grande en Java (que viene con el paquete java.util.regex) no se publicita más.

Recientemente, Java ha saltado al mundo de las expresiones regulares con ambos pies. El paquete java.util.regex también tiene la ventaja de admitir expresiones regulares, y Java proporciona documentación detallada sobre cómo hacerlo. De esta manera, poco a poco se fue desvelando el vago misterio de las expresiones regulares. Hay muchas construcciones de expresiones regulares (quizás las más notables combinaciones de bibliotecas de caracteres) que no se encuentran en Perl.

En el paquete regex, hay dos clases: Pattern y Matcher. La clase Pattern es un objeto que expresa y describe el patrón a buscar, mientras que la clase Matcher es el objeto que realmente afecta la búsqueda. Se agregó otra nueva clase de excepción, PatternSyntaxException, que se generará cuando se encuentre un patrón de búsqueda ilegal.

Incluso si está familiarizado con las expresiones regulares, encontrará que usar expresiones regulares con Java es muy simple. Cabe señalar que para aquellos fanáticos de Perl que han sido mimados por las capacidades de coincidencia de una sola línea de Perl, usar el paquete regex de Java para reemplazarlo puede ser más laborioso que lo que han hecho en el pasado.

Una limitación de este artículo es que no es un tutorial completo sobre el uso de expresiones regulares. Si desea obtener más información sobre las expresiones regulares, le recomiendo leer Mastering Regular Expressions de Jeffrey Frieldl, publicado por O'Reilly. A continuación, enumeraré algunos ejemplos para enseñar a los lectores cómo usar expresiones regulares y cómo usar expresiones regulares de manera más simple.

Diseñar una expresión sencilla que haga coincidir cualquier dígito de un número de teléfono puede resultar complicado porque existen muchos casos diferentes para los formatos de números de teléfono. Todos deben elegir un modelo más eficiente.

Por ejemplo: (212) 555-1212, 212-555-1212 y 212 555 1212, que algunos considerarían equivalentes.

Primero, escribamos una expresión regular.

El primer paso es crear un objeto de patrón que coincida con la subcadena anterior. Una vez ejecutado el programa, el objeto se puede convertir en un objeto general según sea necesario. Se puede construir una expresión regular que coincida con el formato anterior de la siguiente manera: (\d)\s\d-\d, donde el tipo de carácter único \d se utiliza para hacer coincidir cualquier número entre 0 y 9, y el símbolo repetido significa que hay 3 Una notación conveniente para números consecutivos, también equivalente a (\d\d). \También es otro tipo de carácter único más útil que se utiliza para hacer coincidir espacios en blanco, como la tecla de espacio, la tecla de tabulación y el carácter de nueva línea.

¿No es sencillo? Sin embargo, si utiliza este patrón de expresiones regulares en un programa Java, hay dos cosas más que hacer. Los caracteres que preceden a la barra invertida (\) tienen un significado especial para el intérprete de Java. No todos los paquetes Java relacionados con expresiones regulares comprenden y reconocen el carácter de barra invertida (\), aunque podemos intentarlo. Sin embargo, para evitar esta situación, es decir, para pasar completamente el carácter de barra invertida en el objeto de patrón, se deben utilizar caracteres de barra invertida doble. Además, los corchetes también tienen dos significados en las expresiones regulares. Si desea interpretarlos literalmente (es decir, corchetes), debe utilizar caracteres de doble barra invertida (\) antes de los corchetes. Es decir, algo como esto:

\\(\\\)\s\d\d\

Ahora veamos cómo implementar lo que acabamos de describir en código Java Expresión regular . Una cosa para recordar es que cuando se utiliza un paquete para expresiones regulares, es necesario incluir el paquete antes de definir la clase, que es una línea como esta:

import java.util.regex.* ;

El siguiente fragmento de código lee línea por línea de un archivo de texto, busca un número de teléfono dígito por dígito y luego lo envía a la consola cuando se encuentra una coincidencia.

BufferedReader en;

Patrón patrón = Pattern.compile("\(\\d\)\s\d-\\d"); in = new BufferedReader(new FileReader("" teléfono"));

in = new BufferedReader(new FileReader("" teléfono"));

String

while ((s = in.readLine()) != null)

{

Comparador de coincidencias = patrón.matcher(s);

if (matcher.find())

{

System.out.println(matcher.group()) )

}

}

in.close();

Este código resultará familiar para cualquiera que esté familiarizado con la implementación de expresiones regulares en Python o Javascript. En lenguajes como Python y Javascript, o cualquier otro lenguaje, estas expresiones regulares, una vez compiladas explícitamente, se pueden utilizar en cualquier lugar. Comparado con la coincidencia de un solo paso de Perl, parece más complicado, pero en realidad no lo es.

Como puedes imaginar, el método find() se usa para buscar cualquier cadena de destino que coincida con la expresión regular, mientras que el método group() se usa para devolver una cadena que contiene el texto coincidente.

Tenga en cuenta que el código anterior solo se utilizará si cada línea puede contener solo una cadena coincidente de dígitos de números de teléfono. Basta decir que el paquete de expresiones regulares de Java se puede utilizar para buscar múltiples coincidencias en una sola línea. La intención original de este artículo es dar algunos ejemplos simples para inspirar a los lectores a aprender más sobre el paquete de expresiones regulares que viene con Java, por lo que no profundiza.

Muy bonito, ¿no? Pero desafortunadamente, esto es sólo un comparador de números de teléfono. Evidentemente hay dos puntos mejorables. Si puede haber un espacio entre el comienzo del número de teléfono, el código de área y el número local. También podemos hacer coincidir estos casos agregando \s? a la expresión regular, donde el metacarácter ? indica que puede haber 0 o 1 carácter de espacio en el patrón.

El segundo punto es que puede haber un carácter de espacio entre los primeros tres y los últimos cuatro dígitos del número local en lugar de un guión, o en el caso del número ganador, o ningún separador. Sólo 7 números conectados entre sí. Para estos casos, podemos usar (-|)? La expresión regular de esta estructura es un convertidor, que puede coincidir con las situaciones anteriores. Entre ellos, () puede contener el carácter de barra vertical |, que puede coincidir si contiene un carácter de espacio o un guión, y el metacarácter final indica si hay un delimitador.

Finalmente, también es posible que el código de región no esté entre corchetes, en cuyo caso simplemente puede agregar el metacarácter "...", pero esta no es una buena solución. Esto se debe a que también contiene paréntesis no emparejados, como "(555" o "555)". En su lugar, podemos usar otro convertidor para forzar que el número de teléfono contenga paréntesis: (\(\d\)|\d). Si reemplazamos las expresiones regulares en el código anterior con estas expresiones regulares mejoradas, el código anterior se convierte en un comparador de números de teléfono muy útil:

Pattern patrón =

Pattern.compile("( \(\d\\)|\d)\s?\d(-|)?\\);

Sin duda, puedes intentar mejorar aún más el código anterior.

Ahora veamos el segundo ejemplo, adaptado del ejemplo de Friedl. Su función es comprobar si hay palabras repetidas en archivos de texto, lo que se encuentra a menudo en tipografía, y también es un problema con el programa.

Al igual que con los otros ejemplos, se puede usar una variedad de expresiones regulares para hacer coincidir palabras. La más sencilla es probablemente \b\w \b, que tiene la ventaja de usar solo una pequeña cantidad de metacaracteres de expresiones regulares. Entre ellos, el metacarácter \w se usa para hacer coincidir cualquier carácter de las letras a a u. El metacarácter \b se usa para hacer coincidir uno o más caracteres, y el metacarácter \b se usa para hacer coincidir un límite de palabra, que puede ser. un espacio o muchos caracteres diferentes cualquiera de los signos de puntuación (incluyendo comas, puntos, etc.)

Ahora bien, ¿cómo comprobamos si una palabra se repite tres veces? ventaja de las conocidas expresiones regulares. Funcionalidad de escaneo inverso Como se mencionó anteriormente, los paréntesis tienen varios usos diferentes en las expresiones regulares, uno de los cuales es proporcionar un tipo de combinación que se usa para guardar el resultado de una coincidencia o coincidencia parcial (por ejemplo). uso posterior) incluso si se encuentra Lo mismo es cierto para el mismo patrón. Es posible (y a menudo deseable) tener más de un tipo de combinación en la misma expresión regular. Al escanear hacia atrás, puede obtener el resultado coincidente. El enésimo tipo de combinación. El escaneo hacia atrás puede ser muy simple. Se encuentran palabras duplicadas: \b(\w )\s \1\b.

Los corchetes forman un tipo de combinación, que es el primero (y único). ) uno en este tipo de combinación de expresión regular. Escanee hacia atrás para encontrar \1, que se refiere a cualquier palabra que coincida con \w. Por lo tanto, nuestra expresión regular coincide con una palabra que tiene uno o más caracteres de espacio seguidos de la misma palabra. El tipo de localizador final (\b) es crucial para evitar errores si queremos hacer coincidir "Primavera en París" y no "El paquete de expresiones regulares de Java es el tema de este artículo".

Según el formato actual de Java, la expresión regular anterior será: Patrón patrón =Pattern.compile("\b(\w )\s \\1\b");

La última modificación adicional es Hacer que nuestro comparador distinga entre mayúsculas y minúsculas. Por ejemplo, en el siguiente caso: "El tema de este artículo es el paquete regex de Java", esto se puede lograr de manera muy simple con regex, es decir, usando el indicador estático predefinido CASE_INSENSITIVE en la clase Pattern:

Patrón patrón =Pattern .compile("\\b(\w )\s \1\b",

Pattern.CASE_INSENSITIVE);

El tema de las expresiones regulares es rico y complejo y su aplicación en Java La implementación también es muy extensa y requiere un estudio en profundidad del paquete regex, y lo que cubrimos aquí es solo la punta del iceberg. Incluso si es relativamente nuevo en el uso de expresiones regulares, descubrirá rápidamente cuán poderoso y extensible es el paquete regex. Si es un hacker experimentado en expresiones regulares en el campo de Perl u otros lenguajes, luego de usar el paquete regex, se sumergirá de manera segura en el mundo de Java, abandonará otras herramientas y considerará el paquete java regex como una herramienta esencial para tener. en la mano.