Coincidencia de expresiones regulares de Java

1 expresión regular

1.1 ¿Qué es una expresión regular?

Expresión regular: una cadena que define un patrón de búsqueda.

Las expresiones regulares se pueden utilizar para buscar, editar y manipular texto.

El proceso de análisis de expresión regular o modificación de texto es el siguiente: Primero, la expresión regular se aplica a una cadena de texto (texto/cadena), que coincidirá con el texto de izquierda a derecha en un patrón definido, y cada carácter de origen solo coincide una vez.

1.2 Ejemplos

expresión regular fósforo
this is text Coincide exactamente con la cadena "esto es texto"
this\s+is\s+text coincide con la palabra "esto" seguida de uno o más espacios, seguida de la palabra "es", seguida de uno o más espacios, seguida de la palabra "texto"
^\d+(\.\d+)? ^ El patrón de definición debe coincidir con el comienzo de la cadena, d+ coincidir con uno o más números, ? indicar que la declaración entre paréntesis es opcional, \. coincidir con "." y los paréntesis indican agrupación. Ejemplos de coincidencias: "5", "1.5" y "2.21"

2 Reglas para escribir expresiones regulares

2.1 Símbolos coincidentes comunes

expresión regular describir
. Coincide con todos los caracteres individuales excepto las líneas nuevas (líneas nuevas en Linux  \n, líneas nuevas en Windows  \r\n)
^regex La expresión regular debe coincidir con el comienzo de la cadena.
regex$ Regex debe coincidir con el final de la cadena
[abc] Verifique la definición del conjunto, haga coincidir las letras a o b o c
[abc][vz] Compruebe la definición del conjunto, coincide con la letra a o b o c seguida de v o z
[^abc] El modo negado se indica cuando el signo de intercalación  ^ comienza con el primer carácter entre corchetes. Este patrón coincide con todos los caracteres excepto a o b o c
[a-d1-7] Coincidencia de rango, coincide con letras de la a a la d y números del 1 al 7, pero no coincide con d1
XZ Coincide con X seguido directamente de Z
X|Z coincide con X o Z

2.2 Metacaracteres

Un metacarácter es un carácter predefinido.

expresión regular describir
\d coincide con un número,  [0-9] abreviatura de sí
\D coincide con un no dígito,  [^0-9] abreviatura de sí
\s coincide con un espacio,  [ \t\n\x0b\r\f] abreviatura de sí
\S coincide con un espacio no en blanco
\w Coincide con un carácter de palabra (letras mayúsculas y minúsculas, números, guión bajo),  [a-zA-Z_0-9] abreviatura de sí
\W Coincide con un carácter que no es una palabra (caracteres distintos de letras mayúsculas y minúsculas, números y guiones bajos), equivalente a [^\w]

2.3 Eliminatorias

Un calificador define con qué frecuencia puede ocurrir un elemento.

expresión regular describir ejemplo
* Coincidencia >=0,  {0,} abreviatura de sí X* significa que coincide con cero o más letras X .* significa que coincide con cualquier cadena
+ Coincidencia >=1,  {1,} abreviatura de sí X+ significa hacer coincidir una o más letras X
? Partido 1 o 0,  {0,1} abreviatura de sí X? significa coincidir con 0 o 1 letra X
{X} coincide solo con X caracteres \d{3} significa hacer coincidir 3 números, .{10} significa hacer coincidir cualquier cadena con una longitud de 10
{X,Y} coincide con >=X y <=Y \d{1,4} significa acertar al menos 1 y hasta 4 números
*? Si  es  el primer carácter después ? del calificador  * o  + o  ? o  , significa modo no codicioso (tan pocos caracteres coincidentes como sea posible), en lugar del modo codicioso predeterminado{}

2.4 Agrupación y referencias inversas

Los paréntesis  () pueden lograr el efecto de agrupar expresiones regulares.

La agrupación de patrones crea referencias inversas en la expresión regular . La referencia inversa guarda el fragmento de cadena que coincide con el grupo de patrones, lo que nos permite recuperar y usar este fragmento de cadena.

En la sintaxis de reemplazar cadenas con expresiones regulares, es  $ la referencia inversa para hacer referencia al grupo, $0 es la cadena que coincide con el patrón completo (tenga en cuenta que se denota por y en JavaScript  $& ); $1 es la referencia inversa del primer grupo; $2 es A referencia inversa a la segunda agrupación, y así sucesivamente.

Ejemplo:


public class RegexTest {

    public static void main(String[] args) {
        // 去除单词与 , 和 . 之间的空格
        String Str = "Hello , World .";
        String pattern = "(\\w)(\\s+)([.,])";
        // $0 匹配 `(\w)(\s+)([.,])` 结果为 `o空格,` 和 `d空格.`
        // $1 匹配 `(\w)` 结果为 `o` 和 `d`
        // $2 匹配 `(\s+)` 结果为 `空格` 和 `空格`
        // $3 匹配 `([.,])` 结果为 `,` 和 `.`
        System.out.println(Str.replaceAll(pattern, "$1$3")); // Hello, World.
    }
}

En el ejemplo anterior, solíamos  [.] hacer coincidir caracteres ordinarios  . sin usar  [\\.]. Porque el par regular  [] se  .procesará automáticamente como  [\.]caracteres ordinarios  . para hacer coincidir.

2.4.1 Solo agrupamiento pero sin retroreferencias

() Cuando lo agregamos al principio del patrón entre  paréntesis  ?:, significa que este patrón solo agrupa, pero no crea referencias hacia atrás.

Ejemplo:

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

public class RegexTest {

    public static void main(String[] args) {
        String str = "img.jpg";
        // 分组且创建反向引用
        Pattern pattern = Pattern.compile("(jpg|png)");
        Matcher matcher = pattern.matcher(str);
        while (matcher.find()) {
            System.out.println(matcher.group());
            System.out.println(matcher.group(1));
        }
    }
}

resultado de la operación:

jpeg jpeg

Si el código fuente se cambia a:

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

public class RegexTest {

    public static void main(String[] args) {
        String str = "img.jpg";
        // 分组但不创建反向引用
        Pattern pattern = Pattern.compile("(?:jpg|png)");
        Matcher matcher = pattern.matcher(str);
        while (matcher.find()) {
            System.out.println(matcher.group());
            System.out.println(matcher.group(1));
        }
    }
}

resultado de la operación:

jpg 
Excepción en el hilo "principal" java.lang.IndexOutOfBoundsException: No hay grupo 1 
    en java.util.regex.Matcher.group(Matcher.java:538) 
    en com.wuxianjiezh.regex.RegexTest.main(RegexTest.java:15)

2.4.2 Copias retroreferenciadas de grupos

En Java, puede usar paréntesis  ?<name> para guardar el contenido coincidente entre paréntesis como una copia con nombre.

Ejemplo:

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

public class RegexTest {

    public static void main(String[] args) {
        String str = "@wkf 你好啊";
        Pattern pattern = Pattern.compile("@(?<first>\\w+\\s)"); // 保存一个副本
        Matcher matcher = pattern.matcher(str);
        while (matcher.find()) {
            System.out.println(matcher.group());
            System.out.println(matcher.group(1));
            System.out.println(matcher.group("first"));
        }
    }
}

resultado de la operación:

@wkf 
wkf 
wkf

2.5 Anticipación negativa

Podemos crear coincidencias que nieguen el patrón de aserción anticipada, es decir, un patrón en el que una determinada cadena no es seguida por otra cadena.

El patrón de aserción de búsqueda anticipada negada se pasa por  (?!pattern) definición. Por ejemplo, hacemos coincidir "a" no seguida de "b":

un(?!b)

2.6 Especificar el patrón de la expresión regular

Los modificadores de patrón se pueden especificar al comienzo de la expresión regular .

  • (?i) Haga que la expresión regular ignore el caso.
  • (?s) Indica el " modo de una sola línea " para que el normal  . coincida con todos los caracteres, incluidas las líneas nuevas.
  • (?m) Indica el " modo multilínea ", que hace que las sumas regulares  coincidan con el inicio ^ y  $ el final de cada línea de la cadena.

2.7 Barras invertidas en Java

Una barra invertida  \ representa un carácter de escape en Java, lo que significa que  \ tiene un significado predefinido en Java.

Aquí hay dos ejemplos de usos particularmente importantes:

  • Al hacer coincidir  . o  {  o  [ o  ( o  ? o  estos caracteres especiales,  debe   agregarlos delante  . Por ejemplo,   al hacer coincidir, debe escribirse como en Java  , pero es para expresiones  $ regulares  .^*\\.\\.\.
  • Al coincidir  \ , se escribe como en Java  \\\\, pero es para expresiones regulares  \\.

Nota : la cadena de expresión regular en Java tiene dos significados: primero, la cadena de Java se escapa a una cadena que se ajusta a la sintaxis de la expresión regular, y luego la expresión regular con escape se usa para la coincidencia de patrones.

2.8 Ejemplos de puntos propensos a errores

  • [jpg|png] Representa la coincidencia   de cualquiera de los caracteres j en o  p o  g o  p o  n . g
  • (jpg|png) Representa una coincidencia  jpg o  png.

3 Usando expresiones regulares en cadenas

3.1 Método de procesamiento regular de cadena incorporado

Hay cuatro métodos incorporados para ejecutar expresiones regulares en Java, a saber  matches(), , split()), replaceFirst(), replaceAll(). El método Note  replace() no admite expresiones regulares.

método describir
s.matches("regex") Devuelve si solo y si la expresión regular coincide con toda la cadena true
s.split("regex") Cortar una cadena por una expresión regular coincidente
s.replaceFirst("regex", "replacement") reemplazar el primer fragmento de cadena coincidente
s.replaceAll("regex", "replacement") reemplazar todos los caracteres coincidentes

3.2 Ejemplo de código 

public class RegexTest {

    public static void main(String[] args) {
        System.out.println("wxj".matches("wxj"));
        System.out.println("----------");

        String[] array = "w x j".split("\\s");
        for (String item : array) {
            System.out.println(item);
        }
        System.out.println("----------");

        System.out.println("w x j".replaceFirst("\\s", "-"));
        System.out.println("----------");

        System.out.println("w x j".replaceAll("\\s", "-"));
    }
}

 resultado de la operación:

verdadero 
---------- 
w 
x 
j 
---------- 
wx j 
---------- 
wxj

4 patrones y combinación

El uso de expresiones regulares en Java requiere dos clases, a saber,  java.util.regex.Pattern y  java.util.regex.Matcher.

En el primer paso, se crea un objeto de patrón a través de una expresión regular  Pattern.

PatternEl segundo paso es crear un objeto coincidente basado en la cadena especificada  a través del objeto de patrón  Matcher.

El tercer paso es  Matchermanipular cadenas de acuerdo con expresiones regulares haciendo coincidir objetos.

Tomemos un ejemplo para profundizar nuestra comprensión:

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

public class RegexTest {

    public static void main(String[] args) {
        String text = "Hello Regex!";

        Pattern pattern = Pattern.compile("\\w+");
        // Java 中忽略大小写,有两种写法:
        // Pattern pattern = Pattern.compile("\\w+", Pattern.CASE_INSENSITIVE);
        // Pattern pattern = Pattern.compile("(?i)\\w+"); // 推荐写法
        Matcher matcher = pattern.matcher(text);
        // 遍例所有匹配的序列
        while (matcher.find()) {
            System.out.print("Start index: " + matcher.start());
            System.out.print(" End index: " + matcher.end() + " ");
            System.out.println(matcher.group());
        }
        // 创建第两个模式,将空格替换为 tab
        Pattern replace = Pattern.compile("\\s+");
        Matcher matcher2 = replace.matcher(text);
        System.out.println(matcher2.replaceAll("\t"));
    }
}

resultado de la operación:

Start index: 0 End index: 5 Hello
Start index: 6 End index: 11 Regex
Hello    Regex!

5 若干个常用例子

5.1 中文的匹配

[\u4e00-\u9fa5]+ 代表匹配中文字。

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

public class RegexTest {

    public static void main(String[] args) {
        String str = "这是中文";
        Pattern pattern = Pattern.compile("[\\u4e00-\\u9fa5]+");
        Matcher matcher = pattern.matcher(str);
        while (matcher.find()) {
            System.out.println(matcher.group());
        }
    }
}

运行结果:

这是中文

5.2 数字范围的匹配

比如,匹配 1990 到 2017。

注意:这里有个新手易范的错误,就是正则 [1990-2017],实际这个正则只匹配 0 或 1 或 2 或 7 或 9 中的任一个字符。

正则表达式匹配数字范围时,首先要确定最大值与最小值,最后写中间值。

正确的匹配方式:

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

public class RegexTest {

    public static void main(String[] args) {
        String str = "1990\n2010\n2017";
        // 这里应用了 (?m) 的多行匹配模式,只为方便我们测试输出
        // "^1990$|^199[1-9]$|^20[0-1][0-6]$|^2017$" 为判断 1990-2017 正确的正则表达式
        Pattern pattern = Pattern.compile("(?m)^1990$|^199[1-9]$|^20[0-1][0-6]$|^2017$");
        Matcher matcher = pattern.matcher(str);
        while (matcher.find()) {
            System.out.println(matcher.group());
        }
    }
}

运行结果:

1990
2010
2017

5.3 img 标签的匹配

比如,获取图片文件内容,这里我们考虑了一些不规范的 img 标签写法:

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

public class RegexTest {

    public static void main(String[] args) {
        String str = "<img  src='aaa.jpg' /><img src=bbb.png/><img src=\"ccc.png\"/>" +
                "<img src='ddd.exe'/><img src='eee.jpn'/>";
        // 这里我们考虑了一些不规范的 img 标签写法,比如:空格、引号
        Pattern pattern = Pattern.compile("<img\\s+src=(?:['\"])?(?<src>\\w+.(jpg|png))(?:['\"])?\\s*/>");
        Matcher matcher = pattern.matcher(str);
        while (matcher.find()) {
            System.out.println(matcher.group("src"));
        }
    }
}

运行结果:

aaa.jpg
bbb.png
ccc.png

5.4 贪婪与非贪婪模式的匹配

比如,获取 div 标签中的文本内容:

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

public class RegexTest {

    public static void main(String[] args) {
        String str = "<div>文章标题</div><div>发布时间</div>";
        // 贪婪模式
        Pattern pattern = Pattern.compile("<div>(?<title>.+)</div>");
        Matcher matcher = pattern.matcher(str);
        while (matcher.find()) {
            System.out.println(matcher.group("title"));
        }

        System.out.println("--------------");

        // 非贪婪模式
        pattern = Pattern.compile("<div>(?<title>.+?)</div>");
        matcher = pattern.matcher(str);
        while (matcher.find()) {
            System.out.println(matcher.group("title"));
        }
    }
}

运行结果:

文章标题</div><div>发布时间
--------------
文章标题
发布时间

6 推荐两个在线正则工具

Supongo que te gusta

Origin blog.csdn.net/qq_37284798/article/details/129950910
Recomendado
Clasificación