Java - Expresiones regulares

Java proporciona el paquete java.util.regex para la coincidencia de patrones con expresiones regulares. Las expresiones regulares de Java son muy similares al lenguaje de programación Perl y muy fáciles de aprender.

Una expresión regular es una secuencia especial de caracteres que le ayuda a hacer coincidir o encontrar otras cadenas o conjuntos de cadenas, utilizando una sintaxis especializada contenida en un patrón. Se pueden utilizar para buscar, editar o manipular texto y datos.

El paquete java.util.regex consta principalmente de las siguientes tres clases:

  • Pattern Class- Un objeto Pattern es una representación compilada de una expresión regular. La clase Pattern no proporciona constructores públicos. Para crear un patrón, primero debe invocar uno de sus estáticos públicoscompile()métodos, que luego devolverán un objeto Pattern. Estos métodos aceptan una expresión regular como primer argumento.

  • Matcher Class- Un objeto Matcher es el motor que interpreta el patrón y realiza operaciones de coincidencia con una cadena de entrada. Como la clase Pattern, Matcher no define constructores públicos. Obtienes un objeto Matcher invocando elmatcher() método en un objeto Pattern.

  • PatternSyntaxException - Un objeto PatternSyntaxException es una excepción sin marcar que indica un error de sintaxis en un patrón de expresión regular.

Capturar grupos

La captura de grupos es una forma de tratar a varios personajes como una sola unidad. Se crean colocando los caracteres a agrupar dentro de un par de paréntesis. Por ejemplo, la expresión regular (perro) crea un solo grupo que contiene las letras "d", "o" y "g".

Los grupos de captura se numeran contando sus paréntesis de apertura de izquierda a derecha. En la expresión ((A) (B (C))), por ejemplo, hay cuatro grupos de este tipo:

  • ((A)(B(C)))
  • (A)
  • (B(C))
  • (C)

Para saber cuántos grupos están presentes en la expresión, llame al método groupCount en un objeto de comparación. El método groupCount devuelve unint mostrando el número de grupos de captura presentes en el patrón del emparejador.

También hay un grupo especial, el grupo 0, que siempre representa la expresión completa. Este grupo no está incluido en el total informado por groupCount.

Example

El siguiente ejemplo ilustra cómo encontrar una cadena de dígitos de la cadena alfanumérica dada:

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexMatches {

   public static void main( String args[] ) {
      // String to be scanned to find the pattern.
      String line = "This order was placed for QT3000! OK?";
      String pattern = "(.*)(\\d+)(.*)";

      // Create a Pattern object
      Pattern r = Pattern.compile(pattern);

      // Now create matcher object.
      Matcher m = r.matcher(line);
      if (m.find( )) {
         System.out.println("Found value: " + m.group(0) );
         System.out.println("Found value: " + m.group(1) );
         System.out.println("Found value: " + m.group(2) );
      }else {
         System.out.println("NO MATCH");
      }
   }
}

Esto producirá el siguiente resultado:

Output

Found value: This order was placed for QT3000! OK?
Found value: This order was placed for QT300
Found value: 0

Sintaxis de expresiones regulares

Aquí está la tabla que enumera toda la sintaxis de metacaracteres de expresión regular disponible en Java:

Subexpresión Partidos
^ Coincide con el comienzo de la línea.
PS Coincide con el final de la línea.
. Coincide con cualquier carácter individual excepto nueva línea. Utilizandom La opción también le permite coincidir con la nueva línea.
[...] Coincide con cualquier carácter individual entre paréntesis.
[^ ...] Coincide con cualquier carácter individual que no esté entre corchetes.
\UN Comienzo de toda la cadena.
\ z Fin de toda la cadena.
\ Z Fin de toda la cadena excepto el terminador de línea final permitido.
re* Coincide con 0 o más apariciones de la expresión anterior.
re + Coincide con 1 o más de lo anterior.
¿re? Coincide con 0 o 1 aparición de la expresión anterior.
re {n} Coincide exactamente con n número de apariciones de la expresión anterior.
re {n,} Coincide con no más apariciones de la expresión anterior.
re {n, m} Coincide con al menos n y como máximo m apariciones de la expresión anterior.
a | segundo Coincide con a o b.
(re) Agrupa expresiones regulares y recuerda el texto coincidente.
(?: re) Agrupa expresiones regulares sin recordar el texto coincidente.
(?> re) Coincide con el patrón independiente sin retroceso.
\ w Coincide con los caracteres de la palabra.
\ W Coincide con los caracteres que no son palabras.
\ s Coincide con el espacio en blanco. Equivalente a [\ t \ n \ r \ f].
\ S Coincide con el espacio no en blanco.
\re Coincide con los dígitos. Equivalente a [0-9].
\RE Coincide con los no dígitos.
\UN Coincide con el comienzo de la cadena.
\ Z Coincide con el final de la cuerda. Si existe una nueva línea, coincide justo antes de la nueva línea.
\ z Coincide con el final de la cuerda.
\GRAMO Coincide con el punto donde terminó el último partido.
\norte Referencia posterior al grupo de captura número "n".
\segundo Coincide con los límites de la palabra cuando está fuera de los corchetes. Coincide con el retroceso (0x08) cuando está dentro de los corchetes.
\SEGUNDO Coincide con los límites que no son palabras.
\ n, \ t, etc. Coincide con nuevas líneas, retornos de carro, pestañas, etc.
\ Q Escape (entre comillas) todos los caracteres hasta \ E.
\MI Termina la cita comenzada con \ Q.

Métodos de la clase Matcher

Aquí hay una lista de métodos de instancia útiles:

Métodos de índice

Los métodos de índice proporcionan valores de índice útiles que muestran con precisión dónde se encontró la coincidencia en la cadena de entrada:

No Señor. Método y descripción
1

public int start()

Devuelve el índice de inicio de la coincidencia anterior.

2

public int start(int group)

Devuelve el índice de inicio de la subsecuencia capturada por el grupo dado durante la operación de coincidencia anterior.

3

public int end()

Devuelve el desplazamiento después del último carácter coincidente.

4

public int end(int group)

Devuelve el desplazamiento después del último carácter de la subsecuencia capturada por el grupo dado durante la operación de coincidencia anterior.

Métodos de estudio

Los métodos de estudio revisan la cadena de entrada y devuelven un booleano que indica si se encuentra el patrón o no:

No Señor. Método y descripción
1

public boolean lookingAt()

Intenta hacer coincidir la secuencia de entrada, comenzando al principio de la región, con el patrón.

2

public boolean find()

Intenta encontrar la siguiente subsecuencia de la secuencia de entrada que coincide con el patrón.

3

public boolean find(int start)

Restablece este comparador y luego intenta encontrar la siguiente subsecuencia de la secuencia de entrada que coincida con el patrón, comenzando en el índice especificado.

4

public boolean matches()

Intenta hacer coincidir toda la región con el patrón.

Métodos de reemplazo

Los métodos de reemplazo son métodos útiles para reemplazar texto en una cadena de entrada:

No Señor. Método y descripción
1

public Matcher appendReplacement(StringBuffer sb, String replacement)

Implementa un paso de agregar y reemplazar no terminal.

2

public StringBuffer appendTail(StringBuffer sb)

Implementa un paso de agregar y reemplazar terminal.

3

public String replaceAll(String replacement)

Reemplaza cada subsecuencia de la secuencia de entrada que coincide con el patrón con la cadena de reemplazo dada.

4

public String replaceFirst(String replacement)

Reemplaza la primera subsecuencia de la secuencia de entrada que coincide con el patrón con la cadena de reemplazo dada.

5

public static String quoteReplacement(String s)

Devuelve una cadena de reemplazo literal para la cadena especificada. Este método produce una cadena que funcionará como un reemplazo literals en el método appendReplacement de la clase Matcher.

Los métodos de inicio y fin

A continuación se muestra el ejemplo que cuenta el número de veces que aparece la palabra "gato" en la cadena de entrada:

Example

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexMatches {

   private static final String REGEX = "\\bcat\\b";
   private static final String INPUT = "cat cat cat cattie cat";

   public static void main( String args[] ) {
      Pattern p = Pattern.compile(REGEX);
      Matcher m = p.matcher(INPUT);   // get a matcher object
      int count = 0;

      while(m.find()) {
         count++;
         System.out.println("Match number "+count);
         System.out.println("start(): "+m.start());
         System.out.println("end(): "+m.end());
      }
   }
}

Esto producirá el siguiente resultado:

Output

Match number 1
start(): 0
end(): 3
Match number 2
start(): 4
end(): 7
Match number 3
start(): 8
end(): 11
Match number 4
start(): 19
end(): 22

Puede ver que este ejemplo usa límites de palabras para asegurarse de que las letras "c" "a" "t" no sean simplemente una subcadena en una palabra más larga. También proporciona información útil sobre en qué parte de la cadena de entrada se produjo la coincidencia.

El método de inicio devuelve el índice de inicio de la subsecuencia capturada por el grupo dado durante la operación de coincidencia anterior, y el final devuelve el índice del último carácter coincidente, más uno.

Los partidos y los métodos LookingAt

Los métodos match y lookingAt intentan hacer coincidir una secuencia de entrada con un patrón. Sin embargo, la diferencia es que las coincidencias requieren que coincida toda la secuencia de entrada, mientras que lookingAt no.

Ambos métodos siempre comienzan al principio de la cadena de entrada. Aquí está el ejemplo que explica la funcionalidad:

Example

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexMatches {

   private static final String REGEX = "foo";
   private static final String INPUT = "fooooooooooooooooo";
   private static Pattern pattern;
   private static Matcher matcher;

   public static void main( String args[] ) {
      pattern = Pattern.compile(REGEX);
      matcher = pattern.matcher(INPUT);

      System.out.println("Current REGEX is: "+REGEX);
      System.out.println("Current INPUT is: "+INPUT);

      System.out.println("lookingAt(): "+matcher.lookingAt());
      System.out.println("matches(): "+matcher.matches());
   }
}

Esto producirá el siguiente resultado:

Output

Current REGEX is: foo
Current INPUT is: fooooooooooooooooo
lookingAt(): true
matches(): false

Los métodos replaceFirst y replaceAll

Los métodos replaceFirst y replaceAll reemplazan el texto que coincide con una expresión regular determinada. Como indican sus nombres, replaceFirst reemplaza la primera aparición y replaceAll reemplaza todas las ocurrencias.

Aquí está el ejemplo que explica la funcionalidad:

Example

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexMatches {

   private static String REGEX = "dog";
   private static String INPUT = "The dog says meow. " + "All dogs say meow.";
   private static String REPLACE = "cat";

   public static void main(String[] args) {
      Pattern p = Pattern.compile(REGEX);
      
      // get a matcher object
      Matcher m = p.matcher(INPUT); 
      INPUT = m.replaceAll(REPLACE);
      System.out.println(INPUT);
   }
}

Esto producirá el siguiente resultado:

Output

The cat says meow. All cats say meow.

Los métodos appendReplacement y appendTail

La clase Matcher también proporciona los métodos appendReplacement y appendTail para el reemplazo de texto.

Aquí está el ejemplo que explica la funcionalidad:

Example

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexMatches {

   private static String REGEX = "a*b";
   private static String INPUT = "aabfooaabfooabfoob";
   private static String REPLACE = "-";
   public static void main(String[] args) {

      Pattern p = Pattern.compile(REGEX);
      
      // get a matcher object
      Matcher m = p.matcher(INPUT);
      StringBuffer sb = new StringBuffer();
      while(m.find()) {
         m.appendReplacement(sb, REPLACE);
      }
      m.appendTail(sb);
      System.out.println(sb.toString());
   }
}

Esto producirá el siguiente resultado:

Output

-foo-foo-foo-

Métodos de la clase PatternSyntaxException

Una PatternSyntaxException es una excepción sin marcar que indica un error de sintaxis en un patrón de expresión regular. La clase PatternSyntaxException proporciona los siguientes métodos para ayudarlo a determinar qué salió mal:

No Señor. Método y descripción
1

public String getDescription()

Recupera la descripción del error.

2

public int getIndex()

Recupera el índice de errores.

3

public String getPattern()

Recupera el patrón de expresión regular erróneo.

4

public String getMessage()

Devuelve una cadena de varias líneas que contiene la descripción del error de sintaxis y su índice, el patrón de expresión regular erróneo y una indicación visual del índice de error dentro del patrón.