JavaRush /Blog Java /Random-ES /Expresiones regulares en Java (RegEx)

Expresiones regulares en Java (RegEx)

Publicado en el grupo Random-ES
Las expresiones regulares son un tema que los programadores, incluso los más experimentados, suelen dejar para más tarde. Sin embargo, la mayoría de los desarrolladores de Java, tarde o temprano, tendrán que lidiar con el procesamiento de texto. Muy a menudo, con operaciones de búsqueda en el texto y edición. Sin expresiones regulares, un código de programa compacto y productivo asociado con el procesamiento de textos es simplemente impensable. Así que deja de posponerlo, ocupémonos de los “habituales” ahora mismo. Esta no es una tarea tan difícil.

¿Qué es la expresión regular RegEx?

De hecho, una expresión regular (RegEx en Java) es un patrón para buscar una cadena en el texto. En Java, la representación inicial de este patrón es siempre una cadena, es decir, un objeto de la clase String. Sin embargo, no se puede compilar cualquier cadena en una expresión regular, sólo aquellas que siguen las reglas para escribir una expresión regular: la sintaxis definida en la especificación del lenguaje. Para escribir una expresión regular se utilizan caracteres alfabéticos y numéricos, así como metacaracteres, caracteres que tienen un significado especial en la sintaxis de las expresiones regulares. Por ejemplo:
String regex = "java"; // plantilla de cadena "java";
String regex = "\\d{3}"; // plantilla de cadena de tres caracteres numéricos;

Creando expresiones regulares en Java

Para crear una expresión regular en Java, debe seguir dos pasos simples:
  1. escríbalo como una cadena usando la sintaxis de expresión regular;
  2. compila esta cadena en una expresión regular;
Trabajar con expresiones regulares en cualquier programa Java comienza con la creación de un objeto de clase Pattern. Para hacer esto, necesita llamar a uno de los dos métodos estáticos disponibles en la clase compile. El primer método toma un argumento (una cadena literal de una expresión regular, y el segundo) más otro parámetro que activa el modo para comparar la plantilla con el texto:
public static Pattern compile (String literal)
public static Pattern compile (String literal, int flags)
La lista de posibles valores de parámetros flagsse define en la clase Patterny está disponible para nosotros como variables de clase estáticas. Por ejemplo:
Pattern pattern = Pattern.compile("java", Pattern.CASE_INSENSITIVE);//la búsqueda de coincidencias con el patrón se realizará sin distinción entre mayúsculas y minúsculas.
Básicamente, la clase Patternes un constructor de expresiones regulares. En esencia, el método compilellama al constructor privado de la clase Patternpara crear una vista compilada. Este método de creación de una instancia de plantilla se implementa con el objetivo de crearla como un objeto inmutable. Al crear, se realiza una verificación de sintaxis de la expresión regular. Si hay errores en la línea, se genera una excepción PatternSyntaxException.

Sintaxis de expresión regular

La sintaxis de las expresiones regulares se basa en el uso de símbolos <([{\^-=$!|]})?*+.>, que pueden combinarse con caracteres alfabéticos. Según su función, se pueden dividir en varios grupos:
1. Metacaracteres para hacer coincidir límites de línea o texto
Metacarácter Objetivo
^ inicio de línea
ps fin de la línea
\b límite de palabra
\B no hay límite de palabras
\A inicio de entrada
\GRAMO final del partido anterior
\Z final de la entrada
\z final de la entrada
2. Metacaracteres para buscar clases de personajes.
Metacarácter Objetivo
\d símbolo digital
\D carácter no numérico
\s carácter espacial
\S carácter sin espacios en blanco
\w carácter alfanumérico o guión bajo
\W cualquier carácter que no sea alfabético, numérico o guión bajo
. cualquier personaje
3. Metacaracteres para buscar símbolos de edición de texto
Metacarácter Objetivo
\ t carácter de tabulación
\norte carácter de nueva línea
\r carácter de retorno de carro
\F ir a la nueva página
\u0085 carácter de siguiente línea
\u2028 carácter separador de línea
\u2029 símbolo separador de párrafo
4. Metacaracteres para agrupar personajes.
Metacarácter Objetivo
[a B C] cualquiera de los anteriores (a, b o c)
[^abc] cualquier otro que los enumerados (no a, b, c)
[a-zA-Z] fusión de rangos (los caracteres latinos de la a a la z no distinguen entre mayúsculas y minúsculas)
[anuncio[mp]] concatenación de caracteres (a a d y m a p)
[az&&[def]] intersección de símbolos (símbolos d,e,f)
[az&&[^bc]] restando caracteres (caracteres a, dz)
5. Metasímbolos para indicar el número de caracteres - cuantificadores. El cuantificador siempre viene después de un carácter o grupo de caracteres.
Metacarácter Objetivo
? uno o faltante
* cero o más veces
+ una o más veces
{norte} n veces
{norte,} n veces o más
{Nuevo Méjico} no menos de n veces y no más de m veces

Modo cuantificador codicioso

Una característica especial de los cuantificadores es la capacidad de usarlos en diferentes modos: codicioso, súper codicioso y vago. El modo extra codicioso se activa agregando el símbolo " +" después del cuantificador, y el modo perezoso agregando el símbolo " ?". Por ejemplo:
"A.+a" // modo codicioso
"A.++a" // modo demasiado codicioso
"A.+?a" // modo perezoso
Usando esta plantilla como ejemplo, intentemos comprender cómo funcionan los cuantificadores en diferentes modos. De forma predeterminada, el cuantificador funciona en modo codicioso. Esto significa que busca la coincidencia más larga posible en la cadena. Como resultado de ejecutar este código:
public static void main(String[] args) {
    String text = "Egor alla Alejandro";
    Pattern pattern = Pattern.compile("A.+a");
    Matcher matcher = pattern.matcher(text);
    while (matcher.find()) {
        System.out.println(text.substring(matcher.start(), matcher.end()));
    }
}
obtendremos el siguiente resultado: Alla Alexa El algoritmo de búsqueda para un patrón determinado " А.+а" se realiza en la siguiente secuencia:
  1. En el patrón dado, el primer carácter es la letra rusa А. Matcherlo compara con cada carácter del texto, comenzando en la posición cero. En la posición cero de nuestro texto hay un símbolo Е, por lo que Matcherrecorre los caracteres del texto secuencialmente hasta que coincide con el patrón. En nuestro ejemplo, este es el símbolo en la posición número 5.

    Expresiones regulares en Java - 2
  2. Después de encontrar una coincidencia con el primer carácter del patrón, Matcherverifica la coincidencia con el segundo carácter del patrón. En nuestro caso, este es el símbolo " .", que representa cualquier carácter.

    Expresiones regulares en Java - 3

    En la sexta posición está el símbolo de la letra л. Por supuesto, coincide con el patrón "cualquier carácter".

  3. Matcherpasa a comprobar el siguiente carácter del patrón. En nuestra plantilla, se especifica mediante el .+cuantificador " ". Dado que el número de repeticiones de "cualquier carácter" en el patrón es una o más veces, Matchertoma el siguiente carácter de la cadena por turno y verifica que cumpla con el patrón, siempre que se cumpla la condición de "cualquier carácter". en nuestro ejemplo, hasta el final de la línea ( desde la posición No. 7 - No. 18 del texto).

    Expresiones regulares en Java - 4

    De hecho, Matchercaptura toda la línea hasta el final; aquí es donde se manifiesta su "codicia".

  4. Después Matcherde llegar al final del texto y terminar de verificar la А.+parte " " del patrón, Matcher comienza a verificar el resto del patrón: el carácter de la letra а. Dado que el texto en dirección hacia adelante ha finalizado, la verificación se realiza en dirección inversa, comenzando desde el último carácter:

    Expresiones regulares en Java - 5
  5. Matcher"recuerda" el número de repeticiones en el patrón " .+" en el que llegó al final del texto, por lo que reduce el número de repeticiones en uno y verifica el patrón del texto hasta que encuentra una coincidencia: Expresiones regulares en Java - 6

Modo cuantificador ultra codicioso

En el modo súper codicioso, el comparador funciona de manera similar al mecanismo del modo codicioso. La diferencia es que cuando tomas texto hasta el final de la línea, no hay búsqueda hacia atrás. Es decir, las primeras tres etapas del modo súper codicioso serán similares al modo codicioso. Después de capturar la cadena completa, el comparador agrega el resto del patrón y lo compara con la cadena capturada. En nuestro ejemplo, al ejecutar el método principal con el patrón " А.++а", no se encontrarán coincidencias. Expresiones regulares en Java - 7

Modo cuantificador perezoso

  1. En este modo, en la etapa inicial, como en el modo codicioso, se busca una coincidencia con el primer carácter del patrón:

    Expresiones regulares en Java - 8
  2. A continuación, busca una coincidencia con el siguiente carácter del patrón, cualquier carácter:

    Expresiones regulares en Java - 9
  3. A diferencia del modo codicioso, el modo diferido busca la coincidencia más corta en el texto, por lo que después de encontrar una coincidencia con el segundo carácter del patrón, que está especificado por un punto y coincide con el carácter en la posición número 6 del texto, Matchercomprobará si el texto coincide con el resto del patrón: el carácter " а" .

    Expresiones regulares en Java - 10
  4. Dado que no se encontró una coincidencia con el patrón en el texto (en la posición No. 7 del texto está el símbolo " " л), Matcheragrega otro "cualquier carácter" al patrón, ya que se especifica una o más veces, y nuevamente compara el patrón con el texto en las posiciones del No. 5 al No. 8:

    Expresiones regulares en Java - 11
  5. En nuestro caso se encontró una coincidencia, pero aún no se ha llegado al final del texto. Por lo tanto, desde la posición No. 9, la verificación comienza buscando el primer carácter del patrón usando un algoritmo similar y luego se repite hasta el final del texto.

    Expresiones regulares en Java - 12
Como resultado del método, maincuando usamos la А.+?аplantilla " ", obtendremos el siguiente resultado: Alla Alexa Como puede verse en nuestro ejemplo, cuando usamos diferentes modos de cuantificador para la misma plantilla, obtuvimos diferentes resultados. Por tanto, es necesario tener en cuenta esta característica y seleccionar el modo deseado en función del resultado deseado durante la búsqueda.

Caracteres de escape en expresiones regulares

Dado que una expresión regular en Java, o más precisamente su representación inicial, se especifica mediante un literal de cadena, es necesario tener en cuenta las reglas de la especificación de Java que se relacionan con los literales de cadena. En particular, el carácter de barra invertida " \" en cadenas literales en el código fuente de Java se interpreta como un carácter de escape que alerta al compilador que el carácter que le sigue es un carácter especial y debe interpretarse de una manera especial. Por ejemplo:
String s = "The root directory is \nWindows";//envuelve Windows a una nueva línea
String s = "The root directory is \u00A7Windows";//insertar carácter de párrafo antes de Windows
Por lo tanto, en cadenas literales que describen una expresión regular y usan el \carácter " " (por ejemplo, para metacaracteres), se debe duplicar para que el compilador de código de bytes de Java no lo interprete de manera diferente. Por ejemplo:
String regex = "\\s"; // plantilla para buscar caracteres de espacio
String regex = "\"Windows\""; // patrón para buscar la cadena "Windows"
El carácter de doble barra invertida también debe usarse para escapar de caracteres especiales si planeamos usarlos como caracteres "normales". Por ejemplo:
String regex = "How\\?"; // plantilla para buscar la cadena "¿Cómo?"

Métodos de la clase Patrón.

La clase Patterntiene otros métodos para trabajar con expresiones regulares: String pattern()– devuelve la representación de cadena original de la expresión regular a partir de la cual se creó el objeto Pattern:
Pattern pattern = Pattern.compile("abc");
System.out.println(Pattern.pattern())//"abc"
static boolean matches(String regex, CharSequence input)– le permite comparar la expresión regular pasada en el parámetro regex con el texto pasado en el parámetro input. Devuelve: verdadero – si el texto coincide con el patrón; falso – de lo contrario; Ejemplo:
System.out.println(Pattern.matches("A.+a","Allá"));//true
System.out.println(Pattern.matches("A.+a","Egor alla Alejandro"));//false
int flags()– devuelve los flagsvalores de los parámetros de la plantilla que se establecieron cuando se creó, o 0 si este parámetro no se configuró. Ejemplo:
Pattern pattern = Pattern.compile("abc");
System.out.println(pattern.flags());// 0
Pattern pattern = Pattern.compile("abc",Pattern.CASE_INSENSITIVE);
System.out.println(pattern.flags());// 2
String[] split(CharSequence text, int limit)– divide el texto pasado como parámetro en una matriz de elementos String. El parámetro limitdetermina el número máximo de coincidencias que se buscan en el texto:
  • cuando limit>0limit-1se realiza la búsqueda de coincidencias;
  • at limit<0– busca todas las coincidencias en el texto
  • cuando limit=0: busca todas las coincidencias en el texto, mientras que las líneas vacías al final de la matriz se descartan;
Ejemplo:
public static void main(String[] args) {
    String text = "Egor Alla Anna";
    Pattern pattern = Pattern.compile("\\s");
    String[] strings = pattern.split(text,2);
    for (String s : strings) {
        System.out.println(s);
    }
    System.out.println("---------");
    String[] strings1 = pattern.split(text);
    for (String s : strings1) {
        System.out.println(s);
    }
}
Salida de la consola: Egor Alla Anna -------- Egor Alla Anna Consideraremos otro método de clase para crear un objeto Matchera continuación.

Métodos de clase de comparación

Matcheres una clase a partir de la cual se crea un objeto para buscar patrones. Matcher– este es un “motor de búsqueda”, un “motor” de expresiones regulares. Para buscar, necesita que se le den dos cosas: un patrón de búsqueda y una “dirección” para buscar. Para crear un objeto, Matcherla clase proporciona el siguiente método Pattern: рublic Matcher matcher(CharSequence input) Como argumento, el método toma una secuencia de caracteres en los que se realizará la búsqueda. Estos son objetos de clases que implementan la interfaz CharSequence. StringPuede pasar no sólo , sino también , StringBuffery StringBuildercomo argumento . La plantilla de búsqueda es el objeto de clase en el que se llama al método . Ejemplo de creación de un comparador: SegmentCharBufferPatternmatcher
Pattern p = Pattern.compile("a*b");// compiló la expresión regular en una vista
Matcher m = p.matcher("aaaaab");//creé un motor de búsqueda en el texto “aaaaab” usando el patrón "a*b"
Ahora, con la ayuda de nuestro "motor de búsqueda", podemos buscar coincidencias, averiguar la posición de la coincidencia en el texto y reemplazar el texto usando métodos de clase. El método boolean find()busca la siguiente coincidencia en el texto con el patrón. Con este método y el operador de bucle, puede analizar todo el texto según el modelo de evento (realizar las operaciones necesarias cuando ocurre un evento, encontrar una coincidencia en el texto). Por ejemplo, usando los métodos de esta clase, int start()puede int end()determinar las posiciones de las coincidencias en el texto y usando los métodos String replaceFirst(String replacement), String replaceAll(String replacement)reemplazar las coincidencias en el texto con otro texto de reemplazo. Ejemplo:
public static void main(String[] args) {
    String text = "Egor Alla Anna";
    Pattern pattern = Pattern.compile("A.+?a");

    Matcher matcher = pattern.matcher(text);
    while (matcher.find()) {
        int start=matcher.start();
        int end=matcher.end();
        System.out.println("Coincidencia encontrada" + text.substring(start,end) + " с "+ start + " Por " + (end-1) + "posición");
    }
    System.out.println(matcher.replaceFirst("ira"));
    System.out.println(matcher.replaceAll("olga"));
    System.out.println(text);
}
Resultado del programa: Se encontró una coincidencia Alla de las posiciones 5 a 8. Se encontró una coincidencia Anna de las posiciones 10 a 13 Egor Ira Anna Egor Olga Olga Egor Alla Anna Del ejemplo queda claro que los métodos replaceFirstcrean replaceAllun nuevo objeto String, una cadena, que es el texto fuente en el que las coincidencias con la plantilla se reemplazan con el texto pasado al método como argumento. Además, el método replaceFirstreemplaza sólo la primera coincidencia y replaceAlltodas las coincidencias de la prueba. El texto original permanece sin cambios. En esta serie de artículos se puede encontrar el uso de otros métodos de clase Matcher, así como ejemplos de expresiones regulares . Las operaciones más comunes con expresiones regulares cuando se trabaja con texto provienen de clases y están integradas en . Estos son métodos como , , , . Pero, de hecho, "debajo del capó" usan y . Por lo tanto, si necesita reemplazar texto o comparar cadenas en un programa sin escribir código innecesario, utilice los métodos de . Si necesita capacidades avanzadas, piense en clases y . PatternMatcherStringsplitmatchesreplaceFirstreplaceAllPatternMatcherStringPatternMatcher

Conclusión

Una expresión regular se describe en un programa Java utilizando cadenas que coinciden con un patrón definido por las reglas. Cuando se ejecuta el código, Java vuelve a compilar esta cadena en un objeto de clase Patterny utiliza el objeto de clase Matcherpara encontrar coincidencias en el texto. Como dije al principio, las expresiones regulares muchas veces se dejan de lado para más adelante, considerándose un tema difícil. Sin embargo, si comprende los conceptos básicos de sintaxis, metacaracteres, escape y estudia ejemplos de expresiones regulares, resultarán mucho más simples de lo que parecen a primera vista.
Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION