Buscar..


Introducción

Una expresión regular es una secuencia especial de caracteres que ayuda a hacer coincidir o encontrar otras cadenas o conjuntos de cadenas, utilizando una sintaxis especializada contenida en un patrón. Java tiene soporte para el uso de expresiones regulares a través del paquete java.util.regex . Este tema es presentar y ayudar a los desarrolladores a comprender más con ejemplos sobre cómo se deben usar las expresiones regulares en Java.

Sintaxis

  • Pattern patternName = Pattern.compile (regex);
  • Matcher MatcherName = patternName.matcher (textToSearch);
  • matcherName.matches () // Devuelve true si el textToSearch coincide exactamente con la expresión regular
  • matcherName.find () // Busca en textToSearch la primera instancia de una subcadena que coincida con la expresión regular. Las llamadas subsiguientes buscarán el resto de la cadena.
  • matcherName.group (groupNum) // Devuelve la subcadena dentro de un grupo de captura
  • matcherName.group (groupName) // Devuelve la subcadena dentro de un grupo de captura con nombre (Java 7+)

Observaciones

Importaciones

Deberá agregar las siguientes importaciones antes de poder usar Regex:

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

Escollos

En java, una barra diagonal inversa se escapa con una barra diagonal inversa doble, por lo que una barra diagonal inversa en la cadena de expresiones regulares debe ingresarse como una barra diagonal inversa doble. Si necesita escapar de una barra diagonal inversa doble (para hacer coincidir una barra diagonal inversa única con la expresión regular, debe ingresarla como una barra diagonal inversa cuádruple).

Símbolos importantes explicados

Personaje Descripción
* Coincidir con el carácter o subexpresión anterior 0 o más veces
+ Coincidir con el carácter o subexpresión anterior 1 o más veces
? Coincidir con el carácter o subexpresión anterior 0 o 1 veces

Otras lecturas

El tema de expresiones regulares contiene más información sobre expresiones regulares.

Utilizando grupos de captura

Si necesita extraer una parte de la cadena de la cadena de entrada, podemos usar grupos de captura de expresiones regulares.

Para este ejemplo, comenzaremos con una expresión regular de número de teléfono simple:

\d{3}-\d{3}-\d{4}

Si se agregan paréntesis a la expresión regular, cada conjunto de paréntesis se considera un grupo de captura . En este caso, estamos usando lo que se llama grupos de captura numerados:

(\d{3})-(\d{3})-(\d{4})
^-----^ ^-----^ ^-----^
Group 1 Group 2 Group 3

Antes de que podamos usarlo en Java, no debemos olvidar seguir las reglas de las Cadenas, escapando de las barras invertidas, resultando en el siguiente patrón:

"(\\d{3})-(\\d{3})-(\\d{4})"

Primero necesitamos compilar el patrón de expresiones regulares para hacer un Pattern y luego necesitamos un Matcher para hacer coincidir nuestra cadena de entrada con el patrón:

Pattern phonePattern = Pattern.compile("(\\d{3})-(\\d{3})-(\\d{4})");
Matcher phoneMatcher = phonePattern.matcher("abcd800-555-1234wxyz");

A continuación, el Matcher debe encontrar la primera subsecuencia que coincida con la expresión regular:

phoneMatcher.find();

Ahora, usando el método de grupo, podemos extraer los datos de la cadena:

String number = phoneMatcher.group(0); //"800-555-1234" (Group 0 is everything the regex matched)
String aCode = phoneMatcher.group(1); //"800"
String threeDigit = phoneMatcher.group(2); //"555"
String fourDigit = phoneMatcher.group(3); //"1234"

Nota: Matcher.group() puede usarse en lugar de Matcher.group(0) .

Java SE 7

Java 7 introdujo los grupos de captura nombrados. Los grupos de captura nombrados funcionan igual que los grupos de captura numerados (pero con un nombre en lugar de un número), aunque hay cambios leves de sintaxis. El uso de grupos de captura con nombre mejora la legibilidad.

Podemos alterar el código anterior para usar grupos nombrados:

(?<AreaCode>\d{3})-(\d{3})-(\d{4})
^----------------^ ^-----^ ^-----^
AreaCode           Group 2 Group 3

Para obtener los contenidos de "AreaCode", podemos usar:

String aCode = phoneMatcher.group("AreaCode"); //"800"

Usando expresiones regulares con comportamiento personalizado compilando el patrón con banderas

Un Pattern se puede compilar con indicadores, si la expresión regular se utiliza como una String literal, use modificadores en línea:

Pattern pattern = Pattern.compile("foo.", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
pattern.matcher("FOO\n").matches(); // Is true.

/* Had the regex not been compiled case insensitively and singlelined,
 * it would fail because FOO does not match /foo/ and \n (newline)
 * does not match /./.
 */

Pattern anotherPattern = Pattern.compile("(?si)foo");
anotherPattern.matcher("FOO\n").matches(); // Is true.

"foOt".replaceAll("(?si)foo", "ca"); // Returns "cat".

Personajes de escape

Generalmente

Para usar caracteres específicos de expresiones regulares ( ?+| Etc.) en su significado literal, deben escaparse. En expresiones regulares comunes esto se hace mediante una barra invertida \ . Sin embargo, como tiene un significado especial en Java Strings, debes usar una doble barra invertida \\ .

Estos dos ejemplos no funcionarán:

"???".replaceAll ("?", "!"); //java.util.regex.PatternSyntaxException
"???".replaceAll ("\?", "!"); //Invalid escape sequence

Este ejemplo funciona

"???".replaceAll ("\\?", "!"); //"!!!"

División de una cadena delimitada por tuberías

Esto no devuelve el resultado esperado:

"a|b".split ("|"); // [a, |, b]

Esto devuelve el resultado esperado:

"a|b".split ("\\|"); // [a, b]

Escape de barra invertida \

Esto dará un error:

"\\".matches("\\"); // PatternSyntaxException
"\\".matches("\\\"); // Syntax Error

Esto funciona:

"\\".matches("\\\\"); // true

Coincidencia con un regex literal.

Si necesita hacer coincidir caracteres que forman parte de la sintaxis de expresiones regulares, puede marcar todo o parte del patrón como un literal de expresiones regulares.

\Q marca el comienzo del literal regex. \E marca el final de la expresión regular.

// the following throws a PatternSyntaxException because of the un-closed bracket
"[123".matches("[123");

// wrapping the bracket in \Q and \E allows the pattern to match as you would expect.
"[123".matches("\\Q[\\E123"); // returns true

Una forma más fácil de hacerlo sin tener que recordar las secuencias de escape \Q y \E es usar Pattern.quote()

"[123".matches(Pattern.quote("[") + "123"); // returns true

No coincide con una cadena dada

Para hacer coincidir algo que no contiene una cadena dada, uno puede usar lookahead negativo:

Sintaxis de Regex: (?!string-to-not-match)

Ejemplo:

//not matching "popcorn"
String regexString = "^(?!popcorn).*$";
System.out.println("[popcorn] " + ("popcorn".matches(regexString) ? "matched!" : "nope!"));
System.out.println("[unicorn] " + ("unicorn".matches(regexString) ? "matched!" : "nope!"));

Salida:

[popcorn] nope!
[unicorn] matched!

A juego con una barra invertida

Si quieres hacer coincidir una barra invertida en tu expresión regular, tendrás que escapar de ella.

La barra invertida es un carácter de escape en expresiones regulares. Puede usar '\\' para referirse a una sola barra invertida en una expresión regular.

Sin embargo, la barra invertida también es un carácter de escape en las cadenas literales de Java. Para hacer una expresión regular a partir de una cadena literal, debes escapar de cada una de sus barras invertidas. En una cadena, se puede usar el literal '\\\\' para crear una expresión regular con '\\', que a su vez puede coincidir con '\'.

Por ejemplo, considere cadenas coincidentes como "C: \ dir \ myfile.txt". Una expresión regular ([A-Za-z]):\\(.*) Coincidirá y proporcionará la letra de la unidad como un grupo de captura. Tenga en cuenta la barra invertida doble.

Para expresar ese patrón en un literal de cadena de Java, cada una de las barras invertidas en la expresión regular debe escaparse.

    String path = "C:\\dir\\myfile.txt";
    System.out.println( "Local path: " + path ); // "C:\dir\myfile.txt"
    
    String regex = "([A-Za-z]):\\\\.*"; // Four to match one
    System.out.println("Regex:      " + regex ); // "([A-Za-z]):\\(.*)"
    
    Pattern pattern = Pattern.compile( regex );
    Matcher matcher = pattern.matcher( path );
    if ( matcher.matches()) {
        System.out.println( "This path is on drive " + matcher.group( 1 ) + ":.");
        // This path is on drive C:.
    }

Si desea hacer coincidir dos barras diagonales inversas, se encontrará usando ocho en una cadena literal, para representar cuatro en la expresión regular, para hacer coincidir dos.

    String path = "\\\\myhost\\share\\myfile.txt";
    System.out.println( "UNC path: " + path ); // \\myhost\share\myfile.txt"
    
    String regex = "\\\\\\\\(.+?)\\\\(.*)"; // Eight to match two
    System.out.println("Regex:    " + regex ); // \\\\(.+?)\\(.*) 
    
    Pattern pattern = Pattern.compile( regex );
    Matcher matcher = pattern.matcher( path );
    
    if ( matcher.matches()) {
        System.out.println( "This path is on host '" + matcher.group( 1 ) + "'.");
        // This path is on host 'myhost'.
    }


Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow