Le informamos sobre una traducción de una breve guía sobre expresiones regulares en el lenguaje Java, escrita por Jeff Friesen para el sitio web JavaWorld . Para facilitar la lectura, hemos dividido el artículo en varias partes.
Uso de la API de expresiones regulares en programas Java para reconocer y describir patrones
Los caracteres de Java y varios tipos de datos de cadena brindan soporte de bajo nivel para la coincidencia de patrones, pero su uso para este propósito generalmente agrega una complejidad significativa al código. Se obtiene un código más simple y con mayor rendimiento utilizando la API Regex ("API de expresión regular"). Este tutorial lo ayudará a comenzar con expresiones regulares y la API Regex. Primero discutiremos las tres clases más interesantes del paquete en general java.util.regex, y luego echaremos un vistazo al interior de la clase Patterny exploraremos sus sofisticadas construcciones de coincidencia de patrones. Atención: Puede descargar el código fuente (creado por Jeff Friesen para el sitio JavaWorld) de la aplicación de demostración de este artículo desde aquí .
¿Qué son las expresiones regulares?
Una expresión regular (expresión regular/regex/regexp) es una cadena que es un patrón que describe un determinado conjunto de cadenas. El patrón determina qué filas pertenecen al conjunto. El patrón consta de literales y metacaracteres (caracteres con un significado especial en lugar de un significado literal). La coincidencia de patrones es una búsqueda de texto para encontrar coincidencias, es decir, cadenas que coinciden con un patrón de expresión regular. Java admite la coincidencia de patrones a través de su API Regex. Esta API consta de tres clases: Patterny Matcher, PatternSyntaxExceptionubicadas en el paquete java.util.regex:
Los objetos de clase Pattern, también llamados plantillas, son expresiones regulares compiladas.
Los objetos de clase Matcher, o emparejadores, son mecanismos de interpretación de patrones para encontrar coincidencias en secuencias de caracteres (objetos cuyas clases implementan una interfaz java.lang.CharSequencey sirven como fuentes de texto).
Los objetos de clase PatternSyntaxExceptionse utilizan para describir patrones de expresiones regulares no válidos.
Java también proporciona soporte para la coincidencia de patrones a través de varios métodos de java.lang.String. Por ejemplo, la función boolean matches (String regex)regresa truesolo si la cadena que llama coincide exactamente con la expresión regular regex.
Métodos convenientes
matches()y otros métodos de conveniencia de la clase orientados a expresiones regulares Stringse implementan internamente de una manera similar a la API Regex.
Demostración de Regex
Creé una aplicación RegexDemopara demostrar las expresiones regulares de Java y varios métodos de Pattern, Matchery PatternSyntaxException. A continuación se muestra el código fuente de esta aplicación de demostración. Listado 1. Demostración de expresiones regulares
importjava.util.regex.Matcher;importjava.util.regex.Pattern;importjava.util.regex.PatternSyntaxException;publicclassRegexDemo{publicstaticvoidmain(String[] args){if(args.length !=2){System.err.println("usage: java RegexDemo regex input");return;}// Преобразуем символьные последовательности начала новой строки (\n) в символы начала строки.
args[1]= args[1].replaceAll("\\\\n","\n");try{System.out.println("regex = "+ args[0]);System.out.println("input = "+ args[1]);Pattern p =Pattern.compile(args[0]);Matcher m = p.matcher(args[1]);while(m.find())System.out.println("Found ["+ m.group()+"] starting at "+ m.start()+" and ending at "+(m.end()-1));}catch(PatternSyntaxException pse){System.err.println("Неправильное регулярное выражение: "+ pse.getMessage());System.err.println("Описание: "+ pse.getDescription());System.err.println("Позиция: "+ pse.getIndex());System.err.println("Неправильный шаблон: "+ pse.getPattern());}}}
Lo primero que hace un método mainde clase RegexDemoes comprobar su línea de comando. Requiere dos argumentos: el primero es una expresión regular y el segundo es el texto de entrada en el que se buscará la expresión regular. Es posible que necesite utilizar un carácter de nueva línea dentro del texto de entrada (\n). Esto sólo se puede hacer especificando el carácter \seguido del carácter n. La función main()convierte esta secuencia de caracteres al valor Unicode 10. La mayor parte del código RegexDemoestá encerrado en el archivo try-catch. El bloque tryprimero genera la expresión regular dada y el texto de entrada, y luego crea un objeto Patternque almacena la expresión regular compilada (las expresiones regulares se compilan para mejorar el rendimiento de la coincidencia de patrones). Se extrae un comparador del objeto Patterny se utiliza para buscar coincidencias de forma iterativa hasta encontrarlas todas. El bloque catchllama a varios métodos de clase PatternSyntaxExceptionpara recuperar información útil sobre la excepción. Esta información se envía secuencialmente al flujo de salida. No es necesario conocer todavía los detalles de cómo funciona el código: quedarán claros cuando estudiemos la API en la segunda parte del artículo. Sin embargo, debe compilar el Listado 1. Tome el código del Listado 1 y luego escriba el siguiente comando en el símbolo del sistema para compilar RegexDemo: javac RegexDemo.java
La clase Pattern y sus construcciones.
La clase Pattern, la primera de las tres clases que componen la API Regex, es una representación compilada de una expresión regular. La documentación del SDK de clase Patterndescribe una variedad de construcciones de expresiones regulares, pero si no utiliza activamente expresiones regulares, algunas partes de esta documentación pueden resultar confusas. ¿Qué son los cuantificadores y cuál es la diferencia entre cuantificadores codiciosos, reacios y posesivos? ¿Qué son las clases de caracteres, las coincidencias de límites, las referencias anteriores y las expresiones de banderas incrustadas? Responderé a estas y otras preguntas en las siguientes secciones.
cadenas literales
La construcción de expresión regular más simple es una cadena literal. Para que la coincidencia de patrones sea exitosa, alguna parte del texto ingresado debe coincidir con el patrón de esa construcción. Considere el siguiente ejemplo: java RegexDemo apple applet En este ejemplo, intentamos encontrar una coincidencia para un patrón appleen el texto de entrada applet. El siguiente resultado muestra la coincidencia encontrada:
regex = apple
input = applet
Found[apple] starting at 0 and ending at 4
Vemos en el resultado la expresión regular y el texto de entrada, y luego una indicación de detección exitosa appleen el subprograma. Además, se dan las posiciones inicial y final de este partido: 0y 4, respectivamente. La posición inicial indica el primer lugar en el texto donde se encontró una coincidencia y la posición final indica el último punto de la coincidencia. Ahora digamos que dimos la siguiente línea de comando: java RegexDemo apple crabapple Esta vez obtenemos el siguiente resultado, con diferentes posiciones inicial y final:
regex = apple
input = crabapple
Found[apple] starting at 4 and ending at 8
De lo contrario, con y appletcomo expresión regular apple(el texto de entrada) no se encontrarán coincidencias. Toda la expresión regular debe coincidir, pero en este caso, el texto de entrada no contiene tafter apple.
Metacaracteres
Las construcciones de expresiones regulares más interesantes combinan caracteres literales con metacaracteres. Por ejemplo, en una expresión regular a.b, el metacarácter de punto (.)significa cualquier carácter entre ay b. Considere el siguiente ejemplo: java RegexDemo .ox "The quick brown fox jumps over the lazy ox." Este ejemplo utiliza .oxcomo expresión regular y The quick brown fox jumps over the lazy ox.como texto de entrada. RegexDemobusca en el texto coincidencias que comiencen con cualquier carácter y terminen con ox.Los resultados de su ejecución son los siguientes:
regex =.ox
input =The quick brown fox jumps over the lazy ox.
Found[fox] starting at 16 and ending at 18Found[ ox] starting at 39 and ending at 41
En el resultado vemos dos coincidencias: foxy ox(con un carácter de espacio delante). El metacarácter . coincide con un carácter fen el primer caso y un espacio en el segundo. ¿Qué pasa si lo reemplazas .oxcon un metacarácter .? Es decir, lo que obtenemos como resultado de la siguiente línea de comando: java RegexDemo . "The quick brown fox jumps over the lazy ox." Dado que el metacarácter de punto coincide con cualquier carácter, RegexDemogenerará coincidencias encontradas para todos los caracteres (incluido el carácter de punto final) del texto de entrada:
regex =.
input =The quick brown fox jumps over the lazy ox.
Found[T] starting at 0 and ending at 0Found[h] starting at 1 and ending at 1Found[e] starting at 2 and ending at 2Found[] starting at 3 and ending at 3Found[q] starting at 4 and ending at 4Found[u] starting at 5 and ending at 5Found[i] starting at 6 and ending at 6Found[c] starting at 7 and ending at 7Found[k] starting at 8 and ending at 8Found[] starting at 9 and ending at 9Found[b] starting at 10 and ending at 10Found[r] starting at 11 and ending at 11Found[o] starting at 12 and ending at 12Found[w] starting at 13 and ending at 13Found[n] starting at 14 and ending at 14Found[] starting at 15 and ending at 15Found[f] starting at 16 and ending at 16Found[o] starting at 17 and ending at 17Found[x] starting at 18 and ending at 18Found[] starting at 19 and ending at 19Found[j] starting at 20 and ending at 20Found[u] starting at 21 and ending at 21Found[m] starting at 22 and ending at 22Found[p] starting at 23 and ending at 23Found[s] starting at 24 and ending at 24Found[] starting at 25 and ending at 25Found[o] starting at 26 and ending at 26Found[v] starting at 27 and ending at 27Found[e] starting at 28 and ending at 28Found[r] starting at 29 and ending at 29Found[] starting at 30 and ending at 30Found[t] starting at 31 and ending at 31Found[h] starting at 32 and ending at 32Found[e] starting at 33 and ending at 33Found[] starting at 34 and ending at 34Found[l] starting at 35 and ending at 35Found[a] starting at 36 and ending at 36Found[z] starting at 37 and ending at 37Found[y] starting at 38 and ending at 38Found[] starting at 39 and ending at 39Found[o] starting at 40 and ending at 40Found[x] starting at 41 and ending at 41Found[.] starting at 42 and ending at 42
Citar metacaracteres
Para especificar .o cualquier otro metacarácter como carácter literal en una construcción de expresión regular, debe escaparlo de una de las siguientes maneras:
precedido por un carácter de barra invertida;
Coloque este metacarácter entre \Qy \E(por ejemplo, \Q.\E).
Recuerde duplicar cualquier carácter que aparezca en la cadena literal, como String regex = "\\.";barras invertidas (por ejemplo, \\.o \\Q.\\E). No duplique esas barras invertidas que forman parte de un argumento de línea de comando.
Clases de personajes
A veces tienes que limitar las coincidencias que buscas a un conjunto específico de personajes. Por ejemplo, busque en el texto las vocales a, e, iy , oy ucada aparición de una letra vocal se considerará una coincidencia. Para resolver tales problemas, nos ayudarán las clases de caracteres que definen conjuntos de caracteres entre los metacaracteres de corchetes ( [ ]). La clase Patternadmite clases de caracteres simples, clases de rango, clases inversas, de unión, de intersección y de resta. Los veremos todos ahora.
Clases de personajes simples
Una clase de caracteres simple consta de caracteres colocados uno al lado del otro y coincide solo con esos caracteres. Por ejemplo, la clase coincide con [abc]los caracteres ay . Considere el siguiente ejemplo: Como puede ver en los resultados, en este ejemplo solo el carácter para el cual hay una coincidencia en : bcjava RegexDemo [csw] caveccave
regex =[csw]
input = cave
Found[c] starting at 0 and ending at 0
Clases de personajes invertidos
Una clase de carácter invertido comienza con un metacarácter ^y coincide sólo con aquellos caracteres que no están contenidos en él. Por ejemplo, la clase [^abc]coincide con todos los caracteres aexcepto by c. Considere el siguiente ejemplo: java RegexDemo "[^csw]" cave Tenga en cuenta que en mi sistema operativo (Windows) se requieren comillas dobles porque el shell las trata ^como un carácter de escape. Como puede ver, en este ejemplo solo se encontraron los caracteres a, vy e, para los cuales hay coincidencias en cave:
regex =[^csw]
input = cave
Found[a] starting at 1 and ending at 1Found[v] starting at 2 and ending at 2Found[e] starting at 3 and ending at 3
Clases de caracteres de rango
Una clase de caracteres de rango consta de dos caracteres separados por un guión ( -). Todos los caracteres, comenzando con el carácter a la izquierda del guión y terminando con el carácter a la derecha, son parte del rango. Por ejemplo, el rango [a-z]coincide con todas las letras latinas minúsculas. Esto equivale a definir una clase simple [abcdefghijklmnopqrstuvwxyz]. Considere el siguiente ejemplo: java RegexDemo [a-c] clown este ejemplo solo coincidirá con el carácter cque tiene una coincidencia en clown:
regex =[a-c]
input = clown
Found[c] starting at 0 and ending at 0
GO TO FULL VERSION