Categorías
Java Regular Expressions Top 10

Las 10 preguntas principales para la expresión regular de Java

Esta publicación resume las principales preguntas formuladas sobre las expresiones regulares de Java. Como se preguntan con más frecuencia, es posible que también sean muy útiles.

1. ¿Cómo extraer números de una cadena?

Una pregunta común al usar expresiones regulares es extraer todos los números en una matriz de enteros.

En Java, d significa un rango de dígitos (0-9). Usar las clases predefinidas siempre que sea posible hará que su código sea más fácil de leer y eliminará los errores introducidos por clases de caracteres mal formadas. Por favor refiérase a Clases de caracteres predefinidas para más detalles. Tenga en cuenta la primera barra invertida en d. Si está utilizando una construcción de escape dentro de un literal de cadena, debe preceder la barra invertida con otra barra invertida para que la cadena se compile. Es por eso que necesitamos usar d.

List<Integer> numbers = new LinkedList<Integer>();
Pattern p = Pattern.compile("d+");
Matcher m = p.matcher(str); 
while (m.find()) {
  numbers.add(Integer.parseInt(m.group()));
}

2. ¿Cómo dividir Java String por líneas nuevas?

Hay al menos tres formas diferentes de ingresar un carácter de nueva línea, dependiendo del sistema operativo en el que esté trabajando.

r represents CR (Carriage Return), which is used in Unix
n means LF (Line Feed), used in Mac OS
rn means CR + LF, used in Windows

Por lo tanto, la forma más sencilla de dividir una cadena en nuevas líneas es

String lines[] = String.split("r?n");

Pero si no quieres líneas vacías, puedes usar, que también es mi forma favorita:

String.split("[rn]+")

Una forma más robusta, que es realmente independiente del sistema, es la siguiente. Pero recuerde, seguirá obteniendo líneas vacías si dos caracteres de nueva línea se colocan uno al lado del otro.

String.split(System.getProperty("line.separator"));

3. Importancia de Pattern.compile ()

Una expresión regular, especificada como una cadena, primero debe compilarse en una instancia de Patrón clase. Patrón.compilar() El método es la única forma de crear una instancia de objeto. Por tanto, una secuencia de invocación típica es

Pattern p = Pattern.compile("a*b");
Matcher matcher = p.matcher("aaaaab");
assert matcher.matches() == true;

Esencialmente, Patrón.compilar() se utiliza para transformar una expresión regular en una máquina de estados finitos (ver Compiladores: principios, técnicas y herramientas (segunda edición)). Pero todos los estados involucrados en la realización de un partido residen en el emparejador. De esta manera, el Patrón pag se puede reutilizar. Y muchos comparadores pueden compartir el mismo patrón.

  Descarga de PDF de "Java simple"
Matcher anotherMatcher = p.matcher("aab");
assert anotherMatcher.matches() == true;

Patrón.partidos() El método se define como una conveniencia para cuando una expresión regular se usa solo una vez. Este método todavía usa compilar() para obtener la instancia de un Patrón implícitamente y coincide con una cadena. Por lo tanto,

boolean b = Pattern.matches("a*b", "aaaaab");

es equivalente al primer código anterior, aunque para coincidencias repetidas es menos eficiente ya que no permite reutilizar el patrón compilado.

4. ¿Cómo escapar del texto para una expresión regular?

En general, la expresión regular usa «» para escapar de las construcciones, pero es doloroso preceder la barra invertida con otra barra invertida para que la cadena de Java se compile. Hay otra forma para que los usuarios pasen literales de cadena al Patrón, como «$ 5». En lugar de escribir $5 o [$]5, podemos escribir

Pattern.quote("$5");

5. ¿Por qué String.split () necesita un delimitador de tubería para escapar?

Cuerda.separar() divide una cadena alrededor de coincidencias de la expresión regular dada. La expresión Java admite caracteres especiales que afectan la forma en que se hace coincidir un patrón, que se llama metacarácter. | es un metacarácter que se utiliza para hacer coincidir una sola expresión regular entre varias expresiones regulares posibles. Por ejemplo, A|B significa ya sea A o B. Por favor refiérase a Alternancia con el símbolo de barra vertical o tubería para más detalles. Por lo tanto, para usar | como literal, debe escapar agregando delante de ella, como |.

6. ¿Cómo podemos igualar unnorteBnorte con Java regex?

Este es el idioma de todas las cadenas no vacías que constan de un número de aseguido de un número igual de bes como ab, aabb, y aaabbb. Se puede demostrar que este lenguaje es gramática libre de contexto S → aSb | ab, y por lo tanto un lenguaje no regular.

Sin embargo, las implementaciones de expresiones regulares de Java pueden reconocer más que solo lenguajes regulares. Es decir, no son «regulares» según la definición de la teoría formal del lenguaje. Utilizando mirar hacia el futuro y coincidencia de autorreferencia lo logrará. Aquí daré primero la expresión regular final y luego la explicaré un poco. Para una explicación completa, lo recomendaría leer ¿Cómo podemos hacer coincidir un ^ nb ^ n con Java regex?.

Pattern p = Pattern.compile("(?x)(?:a(?= a*(1?+b)))+1");
// true
System.out.println(p.matcher("aaabbb").matches());
// false
System.out.println(p.matcher("aaaabbb").matches());
// false
System.out.println(p.matcher("aaabbbb").matches());
// false
System.out.println(p.matcher("caaabbb").matches());
  Serialización de Java

En lugar de explicar la sintaxis de esta compleja expresión regular, prefiero decir un poco cómo funciona.

  1. En la primera iteración, se detiene en la primera a luego mira hacia adelante (después de omitir algunos as usando a*) si hay un b. Esto se logró utilizando (?:a(?= a*(1?+b))). Si coincide, 1, la coincidencia de autorreferencia, coincidirá con los elementos entre paréntesis muy internos, que es un solo b en la primera iteración.
  2. En la segunda iteración, la expresión se detendrá en la segunda a, luego mira hacia adelante (de nuevo saltando as) para ver si habrá b. Pero esta vez, 1+b es en realidad equivalente a bb, por lo tanto dos bs tienen que coincidir. Si es así, 1 será cambiado a bb después de la segunda iteración.
  3. En el norteth iteración, la expresión se detiene en el norteth a y mira si hay norte bs adelante.

De esta forma, la expresión puede contar el número de asy coincidir si el número de bs seguido de a es igual.

7. ¿Cómo reemplazar 2 o más espacios con un solo espacio en una cadena y eliminar solo los espacios iniciales?

Cuerda.reemplaza todo() reemplaza cada subcadena que coincide con la expresión regular dada con el reemplazo dado. «2 o más espacios» se pueden expresar mediante una expresión regular [ ]+. Por lo tanto, el siguiente código funcionará. Tenga en cuenta que, en última instancia, la solución no eliminará todos los espacios en blanco iniciales y finales. Si desea que se eliminen, puede utilizar Cuerda.podar() En la tuberia.

String line = "  aa bbbbb   ccc     d  ";
// " aa bbbbb ccc d "
System.out.println(line.replaceAll("[s]+", " "));

8. ¿Cómo determinar si un número es primo con expresión regular?

public static void main(String[] args) {
  // false
  System.out.println(prime(1));
  // true
  System.out.println(prime(2));
  // true
  System.out.println(prime(3));
  // true
  System.out.println(prime(5));
  // false
  System.out.println(prime(8));
  // true
  System.out.println(prime(13));
  // false
  System.out.println(prime(14));
  // false
  System.out.println(prime(15));
}
 
public static boolean prime(int n) {
  return !new String(new char[n]).matches(".?|(..+?)1+");
}

La función primero genera norte número de caracteres e intenta ver si esa cadena coincide .?|(..+?)1+. Si es primo, la expresión devolverá falso y el ! invertirá el resultado.

  ¿Cómo funcionan las interfaces de función en Java 8?

La primera parte .? solo intenta asegurarse de que 1 no sea un cebador. La parte mágica es la segunda parte donde se usa la referencia inversa. (..+?)1+ primer intento de coincidencias norte longitud de los caracteres, luego repítalo varias veces 1+.

Por definición, un número primo es un número natural mayor que 1 que no tiene divisores positivos distintos de 1 y él mismo. Eso significa que si a = n * m luego a no es un primo. Nuevo Méjico se puede explicar con más detalle «repetir norte metro veces «, y eso es exactamente lo que hace la expresión regular: coincide norte longitud de caracteres usando (..+?), luego repítelo metro veces usando 1+. Por lo tanto, si el patrón coincide, el número no es primo, de lo contrario lo es. Recuerda que ! invertirá el resultado.

9. ¿Cómo dividir una cadena separada por comas pero ignorando las comas entre comillas?

Ha llegado al punto en que las expresiones regulares se rompen. Es mejor y más ordenado escribir un divisor simple y maneja casos especiales como lo desee.

Alternativamente, puede imitar el funcionamiento de una máquina de estados finitos, utilizando una instrucción switch o if-else. Se adjunta un fragmento de código.

public static void main(String[] args) {
  String line = "aaa,bbb,"c,c",dd;dd,"e,e";
  List<String> toks = splitComma(line);
  for (String t : toks) {
    System.out.println("> " + t);
  }
}
 
private static List<String> splitComma(String str) {
  int start = 0;
  List<String> toks = new ArrayList<String>();
  boolean withinQuote = false;
  for (int end = 0; end < str.length(); end++) {
    char c = str.charAt(end);
    switch(c) {
    case ',':
      if (!withinQuote) {
        toks.add(str.substring(start, end));
        start = end + 1;
      }
      break;
    case '"':
      withinQuote = !withinQuote;
      break;
    }
  }
  if (start < str.length()) {
    toks.add(str.substring(start));
  }
  return toks;
}

10. Cómo usar backreferences en expresiones regulares de Java

Las referencias inversas son otra característica útil en la expresión regular de Java.

Por Programación.Click

Más de 20 años programando en diferentes lenguajes de programación. Apasionado del code clean y el terminar lo que se empieza. ¿Programamos de verdad?

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *