Java Expresiones Regulares

Las expresiones regulares definen patrones de cadenas.

Las expresiones regulares se pueden usar para buscar, editar o procesar texto.

Las expresiones regulares no se limitan a un solo idioma, pero hay diferencias sutiles en cada lenguaje.

Java proporciona el paquete java.util.regex, que contiene las clases Pattern y Matcher, para manejar operaciones de coincidencia de expresiones regulares.

Ejemplos de expresiones regulares

Una cadena es en realidad una simple expresión regular, por ejemploHello WorldLa expresión regular coincide con la cadena "Hello World".

.El (punto) también es una expresión regular que coincide con cualquier carácter, como "a" o "1".

La siguiente tabla enumera algunos ejemplos y descripciones de expresiones regulares:

Expresión regular Descripción

this is text

Coincide con la cadena "this is text"

this\s+is\s+text

Observa que en la cadena\s+。

coincide con lo que sigue a la palabra "this"\s+puede coincidir con varios espacios, luego coincide con la cadena is, y después\s+coincide con varios espacios y luego con la cadena text.

Puede coincidir con este ejemplo: this is text

^\d+(\.\d+)?

^ define con qué comienza

\d+ coincide con uno o más dígitos

? establece que la opción entre paréntesis es opcional

\. coincide con "."

Ejemplos que puede coincidir: "5", "1.5" y "2.21".

Para más contenido sobre expresiones regulares, consulta:Expresiones regulares - Tutorial


El paquete java.util.regex

java.util.regexEl paquete java.util.regex es un paquete en la biblioteca estándar de Java utilizado para admitir operaciones de expresiones regulares.

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

  • Clase Pattern:

    Un objeto pattern es una representación compilada de una expresión regular. La clase Pattern no tiene constructores públicos. Para crear un objeto Pattern, primero debes llamar a su método estático público compile, que devuelve un objeto Pattern. Este método acepta una expresión regular como su primer parámetro.

  • Clase Matcher:

    Un objeto Matcher es el motor que interpreta y realiza operaciones de coincidencia en una cadena de entrada. Al igual que la clase Pattern, Matcher tampoco tiene constructores públicos. Debes llamar al método matcher de un objeto Pattern para obtener un objeto Matcher.

  • PatternSyntaxException:

    PatternSyntaxException es una clase de excepción no verificada que indica un error de sintaxis en un patrón de expresión regular.

El siguiente ejemplo utiliza una expresión regular.*ejemplo.*para buscar si la cadena contieneejemplola subcadena:

Ejemplo

import java.util.regex.*; class RegexExample1{ public static void main(String[] args){ String content = "I am noob " + "from example.com."; String pattern = ".*ejemplo.*"; boolean isMatch = Pattern.matches(pattern, content); System.out.println("¿La cadena contiene la subcadena 'ejemplo'?" + isMatch); } }

El resultado de salida del ejemplo es:

¿La cadena contiene la subcadena 'ejemplo'? true

Grupos de captura

Los grupos de captura son un método para tratar múltiples caracteres como una sola unidad, creados agrupando caracteres entre paréntesis.

Por ejemplo, la expresión regular (dog) crea un solo grupo que contiene "d", "o" y "g".

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

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

Puedes usar el método groupCount del objeto matcher para ver cuántos grupos tiene la expresión. El método groupCount devuelve un valor int que indica cuántos grupos de captura tiene actualmente el objeto matcher.

También hay un grupo especial (group(0)) que siempre representa toda la expresión. Este grupo no está incluido en el valor devuelto por groupCount.

Ejemplo

El siguiente ejemplo muestra cómo encontrar cadenas de dígitos en una cadena dada:

Código del archivo RegexMatches.java:

import java.util.regex.Matcher; import java.util.regex.Pattern; public class RegexMatches { public static void main( String[] args ){ //Buscar en la cadena según el patrón especificado String line = "This order was placed for QT3000! OK?"; String pattern = "(\\D*)(\\d+)(.*)"; //Crear un objeto Pattern Pattern r = Pattern.compile(pattern); //Ahora crear un objeto matcher 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) ); System.out.println("Found value: " + m.group(3) ); } else { System.out.println("NO MATCH"); } } }

El resultado de compilar y ejecutar el ejemplo anterior es el siguiente:

Found value: This order was placed for QT3000! OK?
Found value: This order was placed for QT
Found value: 3000
Found value: ! OK?

Sintaxis de expresiones regulares

En otros lenguajes,\\significa:Quiero insertar una barra invertida normal (literal) en la expresión regular; no le des ningún significado especial.

En Java,\\significa:Quiero insertar una barra invertida de expresión regular, para que el carácter siguiente tenga un significado especial.

Por lo tanto, en otros lenguajes (como Perl), una barra invertida\es suficiente para tener el efecto de escape, mientras que en Java, en las expresiones regulares, se necesitan dos barras invertidas para que se analicen como el escape de otros lenguajes. También se puede entender simplemente que en las expresiones regulares de Java, dos\\representan una\, por eso la expresión regular para representar un dígito es\\d, y para representar una barra invertida normal es\\。

System.out.print("\\");    // 输出为 \
System.out.print("\\\\");  // 输出为 \\

carácter

Descripción

\

Marca el siguiente carácter como carácter especial, texto, referencia inversa o escape octal. Por ejemplo,ncoincide con el caráctern。\ncoincide con un carácter de nueva línea. La secuencia\\\\coincide con\\ ,\\(coincide con(。

^

Coincide con la posición inicial de la cadena de entrada. Si se establece laRegExppropiedadMultilinedel objeto, ^ también coincidirá con la posición después de '\n' o '\r'.

$

Coincide con la posición final de la cadena de entrada. Si se establece laRegExppropiedadMultilinedel objeto, $ también coincidirá con la posición antes de '\n' o '\r'.

*

Coincide con el carácter o subexpresión anteriores cero o más veces. Por ejemplo, zo* coincide con "z" y "zoo". * equivale a {0,}.

+

Coincide con el carácter o subexpresión anteriores una o más veces. Por ejemplo, "zo+" coincide con "zo" y "zoo", pero no con "z". + equivale a {1,}.

?

Coincide con el carácter o subexpresión anteriores cero o una vez. Por ejemplo, "do(es)?" coincide con "do" o con "do" en "does". ? equivale a {0,1}.

{n}

n Es un entero no negativo. Coincide exactamentenveces. Por ejemplo, "o{2}" no coincide con la "o" en "Bob", pero coincide con las dos "o" en "food".

{n,}

n Es un entero no negativo. Coincide al menosn veces. Por ejemplo, "o{2,}" no coincide con la "o" en "Bob", pero coincide con todas las o en "foooood". "o{1,}" equivale a "o+". "o{0,}" equivale a "o*".

{n,m}

mynEs un entero no negativo, donden <= m. Coincide al menosnveces, como máximomveces. Por ejemplo, "o{1,3}" coincide con las primeras tres o en "fooooood". 'o{0,1}' equivale a 'o?'. Nota: no puedes insertar espacios entre la coma y los números.

?

Cuando este carácter sigue inmediatamente a cualquier otro cuantificador (*, +, ?, {n}、{n,}、{n,m}), el patrón de coincidencia es "no codicioso". El patrón "no codicioso" coincide con la cadena más corta posible encontrada, mientras que el patrón "codicioso" predeterminado coincide con la cadena más larga posible encontrada. Por ejemplo, en la cadena "oooo", "o+?" solo coincide con una sola "o", mientras que "o+" coincide con todas las "o".

.

Coincide con cualquier carácter individual excepto "\r\n". Para coincidir con cualquier carácter, incluido "\r\n", usa un patrón como "[\s\S]".

(pattern)

Coincide conpatterny captura la subexpresión coincidente. Puedes usar$0…$9la propiedad para recuperar la coincidencia capturada de la colección "Coincidencias" del resultado. Para coincidir con los caracteres de paréntesis ( ), usa "\(" o "\)".

(?:pattern)

Coincide conpatternpero no captura la subexpresión de la coincidencia; es decir, es una coincidencia no capturadora que no se almacena para uso posterior. Esto es útil para combinar partes de un patrón con el carácter "o" (|). Por ejemplo, 'industr(?:y|ies)' es una expresión más económica que 'industry|industries'.

(?=pattern)

Subexpresión que realiza una búsqueda anticipada positiva (lookahead), la cual coincide con una cadena que se encuentra al inicio de la coincidenciapatternde la cadena. Es una coincidencia no capturadora, es decir, no se puede capturar para uso posterior. Por ejemplo, 'Windows (?=95|98|NT|2000)' coincide con "Windows" en "Windows 2000", pero no coincide con "Windows" en "Windows 3.1". La anticipación no consume caracteres; es decir, después de que ocurre la coincidencia, la búsqueda de la siguiente coincidencia continúa inmediatamente después de la coincidencia anterior, no después de los caracteres que componen la anticipación.

(?!pattern)

Subexpresión que realiza una búsqueda anticipada negativa (lookahead negativo), la cual coincide con una cadena de búsqueda que no se encuentra al inicio de la coincidenciapatternde la cadena. Es una coincidencia no capturadora, es decir, no se puede capturar para uso posterior. Por ejemplo, 'Windows (?!95|98|NT|2000)' coincide con "Windows" en "Windows 3.1", pero no coincide con "Windows" en "Windows 2000". La anticipación no consume caracteres; es decir, después de que ocurre la coincidencia, la búsqueda de la siguiente coincidencia continúa inmediatamente después de la coincidencia anterior, no después de los caracteres que componen la anticipación.

x|y

Coincide conxoy. Por ejemplo, 'z|food' coincide con 'z' o 'food'. '(z|f)ood' coincide con 'zood' o 'food'.

[xyz]

Conjunto de caracteres. Coincide con cualquier carácter incluido. Por ejemplo, '[abc]' coincide con 'a' en 'plain'.

[^xyz]

Conjunto de caracteres negado. Coincide con cualquier carácter no incluido. Por ejemplo, '[^abc]' coincide con 'p', 'l', 'i', 'n' en 'plain'.

[a-z]

Rango de caracteres. Coincide con cualquier carácter dentro del rango especificado. Por ejemplo, '[a-z]' coincide con cualquier letra minúscula en el rango de 'a' a 'z'.

[^a-z]

Rango de caracteres negado. Coincide con cualquier carácter que no esté en el rango especificado. Por ejemplo, '[^a-z]' coincide con cualquier carácter que no esté en el rango de 'a' a 'z'.

\b

Coincide con un límite de palabra, es decir, la posición entre una palabra y un espacio. Por ejemplo, 'er\b' coincide con 'er' en 'never', pero no coincide con 'er' en 'verb'.

\B

Coincide con un límite de no palabra. 'er\B' coincide con 'er' en 'verb', pero no coincide con 'er' en 'never'.

\cx

Coincide conxel carácter de control indicado. Por ejemplo, \cM coincide con Control-M o retorno de carro.xEl valor de este carácter debe estar entre A-Z o a-z. Si no es así, se asume que c es el propio carácter 'c'.

\d

Coincide con un carácter de dígito. Equivalente a [0-9].

\D

Coincide con un carácter que no es un dígito. Equivalente a [^0-9].

\f

Coincide con un carácter de avance de página. Equivalente a \x0c y \cL.

\n

Coincide con un carácter de nueva línea. Equivalente a \x0a y \cJ.

\r

Coincide con un retorno de carro. Equivalente a \x0d y \cM.

\s

Coincide con cualquier carácter de espacio en blanco, incluidos espacio, tabulación, avance de página, etc. Equivalente a [ \f\n\r\t\v].

\S

Coincide con cualquier carácter que no sea un espacio en blanco. Equivalente a [^ \f\n\r\t\v].

\t

Coincide con un carácter de tabulación. Equivalente a \x09 y \cI.

\v

Coincide con un carácter de tabulación vertical. Equivalente a \x0b y \cK.

\w

Coincide con cualquier carácter de palabra, incluido el subrayado. Equivalente a '[A-Za-z0-9_]'.

\W

Coincide con cualquier carácter que no sea de palabra. Equivalente a '[^A-Za-z0-9_]'.

\xn

Coincide conn, dondenes un código de escape hexadecimal. El código de escape hexadecimal debe tener exactamente dos dígitos de longitud. Por ejemplo, '\x41' coincide con 'A'. '\x041' es equivalente a '\x04' & '1'. Permite utilizar códigos ASCII en expresiones regulares.

\num

Coincide connum, dondenumes un entero positivo. Referencia inversa a la coincidencia capturada. Por ejemplo, '(.)\1' coincide con dos caracteres idénticos consecutivos.

\n

Identifica un código de escape octal o una referencia inversa. Si \nestá precedido por al menosnsubexpresiones capturadas, entoncesnes una referencia inversa. De lo contrario, sines un dígito octal (0-7), entoncesnes un código de escape octal.

\nm

Identifica un código de escape octal o una referencia inversa. Si \nmestá precedido por al menosnmsubexpresiones capturadas, entoncesnmes una referencia inversa. Si \nmestá precedido por al menosncapturas, entoncesnes una referencia inversa, seguida del carácterm. Si no existe ninguno de los dos casos anteriores, entonces \nmcoincide con el valor octalnm, donden ymes un dígito octal (0-7).

\nml

Cuandones un dígito octal (0-3),mylcuando es un dígito octal (0-7), coincide con el código de escape octalnml。

\un

Coincide conn, dondenes un carácter Unicode representado por cuatro dígitos hexadecimales. Por ejemplo, \u00A9 coincide con el símbolo de copyright (©).

Según los requisitos de Java Language Specification, las barras invertidas en las cadenas de código fuente de Java se interpretan como escapes Unicode u otros escapes de caracteres. Por lo tanto, se deben usar dos barras invertidas en los literales de cadena para indicar que la expresión regular está protegida y no será interpretada por el compilador de bytecode de Java. Por ejemplo, cuando se interpreta como expresión regular, el literal de cadena "\b" coincide con un solo carácter de retroceso, mientras que "\\b" coincide con un límite de palabra. El literal de cadena "\(hello\)" es ilegal y provocará un error en tiempo de compilación; para coincidir con la cadena (hello), se debe usar el literal de cadena "\\(hello\\)".


Métodos de la clase Matcher

Métodos de índice

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

N.º Método y descripción
1 public int start()
Devuelve el índice inicial de la coincidencia anterior.
2 public int start(int group)
Devuelve el índice inicial de la subsecuencia capturada por el grupo dado durante la operación de coincidencia anterior.
3 public int end()
Devuelve el desplazamiento posterior al último carácter coincidente.
4 public int end(int group)
Devuelve el desplazamiento posterior al último carácter de la subsecuencia capturada por el grupo dado durante la operación de coincidencia anterior.

Métodos de búsqueda

Los métodos de búsqueda se utilizan para examinar la cadena de entrada y devolver un valor booleano que indica si se encontró el patrón:

N.º Método y descripción
1 public boolean lookingAt()
Intenta hacer coincidir la secuencia de entrada, comenzando desde el inicio de la región, con el patrón.
2 public boolean find()
Intenta encontrar la siguiente subsecuencia de la secuencia de entrada que coincida con el patrón.
3 public boolean find(int start)
Restablece este matcher y luego intenta encontrar la siguiente subsecuencia de la secuencia de entrada, que comience en el índice especificado, que coincida con el patrón.
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 para reemplazar texto en la cadena de entrada:

N.º Método y descripción
1 public Matcher appendReplacement(StringBuffer sb, String replacement)
Implementa los pasos de adición y reemplazo no terminales.
2 public StringBuffer appendTail(StringBuffer sb)
Implementa los pasos de adición y reemplazo terminales.
3 public String replaceAll(String replacement)
Reemplaza cada subsecuencia de la secuencia de entrada que coincida con el patrón por la cadena de reemplazo dada.
4 public String replaceFirst(String replacement)
Reemplaza la primera subsecuencia de la secuencia de entrada que coincida con el patrón por 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 devuelve una cadena que funciona como un literal de cadena pasado al método appendReplacement de la clase Matcher.

Los métodos start y end

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

Código del archivo RegexMatches.java:

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); //Obtener el objeto matcher 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()); } } }

El resultado de compilar y ejecutar el ejemplo anterior es el siguiente:

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

Se puede ver que este ejemplo utiliza límites de palabra para asegurar que las letras 'c', 'a', 't' no sean simplemente una subcadena de una palabra más larga. También proporciona información útil sobre dónde ocurren las coincidencias en la cadena de entrada.

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

Los métodos matches y lookingAt

Los métodos matches y lookingAt se utilizan ambos para intentar hacer coincidir una secuencia de entrada con un patrón. La diferencia es que matches exige que toda la secuencia coincida, mientras que lookingAt no lo exige.

El método lookingAt, aunque no requiere que toda la oración coincida, sí requiere que la coincidencia comience desde el primer carácter.

Estos dos métodos se utilizan a menudo al inicio de la cadena de entrada.

Explicamos esta funcionalidad mediante el siguiente ejemplo:

Código del archivo RegexMatches.java:

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 final String INPUT2 = "ooooofoooooooooooo"; private static Pattern pattern; private static Matcher matcher; private static Matcher matcher2; public static void main( String[] args ){ pattern = Pattern.compile(REGEX); matcher = pattern.matcher(INPUT); matcher2 = pattern.matcher(INPUT2); System.out.println("Current REGEX is: "+REGEX); System.out.println("Current INPUT is: "+INPUT); System.out.println("Current INPUT2 is: "+INPUT2); System.out.println("lookingAt(): "+matcher.lookingAt()); System.out.println("matches(): "+matcher.matches()); System.out.println("lookingAt(): "+matcher2.lookingAt()); } }

El resultado de compilar y ejecutar el ejemplo anterior es el siguiente:

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

Los métodos replaceFirst y replaceAll

Los métodos replaceFirst y replaceAll se utilizan para reemplazar texto que coincide con la expresión regular. La diferencia es que replaceFirst reemplaza la primera coincidencia, mientras que replaceAll reemplaza todas las coincidencias.

El siguiente ejemplo explica esta función:

Código del archivo RegexMatches.java:

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); } }

El resultado de compilar y ejecutar el ejemplo anterior es el siguiente:

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:

Vea el siguiente ejemplo para explicar esta función:

Código del archivo RegexMatches.java:

import java.util.regex.Matcher; import java.util.regex.Pattern; public class RegexMatches { private static String REGEX = "a*b"; private static String INPUT = "aabfooaabfooabfoobkkk"; private static String REPLACE = "-"; public static void main(String[] args) { Pattern p = Pattern.compile(REGEX); //Obtener el objeto matcher Matcher m = p.matcher(INPUT); StringBuffer sb = new StringBuffer(); while(m.find()){ m.appendReplacement(sb,REPLACE); } m.appendTail(sb); System.out.println(sb.toString()); } }

El resultado de compilar y ejecutar el ejemplo anterior es el siguiente:

-foo-foo-foo-kkk

Métodos de la clase PatternSyntaxException

PatternSyntaxException es una clase de excepción no comprobada que indica un error de sintaxis en un patrón de expresión regular.

La clase PatternSyntaxException proporciona los siguientes métodos para ayudarnos a ver qué error ha ocurrido.

N.º Método y descripción
1 public String getDescription()
Obtiene la descripción del error.
2 public int getIndex()
Obtiene el índice del error.
3 public String getPattern()
Obtiene el patrón de expresión regular del error.
4 public String getMessage()
Devuelve una cadena multilínea que incluye 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 del error en el patrón.
Otras extensiones