Categorías
Regular Expressions

Prueba de expresión regular de Java en línea

Aquí es una prueba de expresiones regulares en línea para Java. Por ejemplo, para buscar todos los comentarios en un archivo de código fuente.

Primero ingrese //.* como expresión regular, ingrese algunas cadenas para probar, como «// testing», «testing».

Cuando se envía, la página web da el siguiente resultado.

Como referencia para usar la expresión regular, aquí es una guía bastante buena y breve.

Categorías
Regular Expressions

Expresión regular: excluir una palabra / cadena

Si desea excluir una determinada palabra / cadena en un patrón de búsqueda, una buena forma de hacerlo es la función de aserción de expresión regular. Es indispensable si desea hacer coincidir algo no seguido de otra cosa.

Un ejemplo simple

String str = "programcreek";
Pattern p = Pattern.compile(".*program(?=creek).*");
Matcher m = p.matcher(str);
 
if(m.matches()){
	System.out.println("Match!");
}else{
	System.out.println("No");
}

1. Mire hacia adelante

En el ejemplo anterior, si desea buscar «programcreek», pero no «programriver». Puedes usar el patrón:

.*program(?=creek).*

partidos de programcreek
programador no coincide

? = es una anticipación positiva y?! es una anticipación negativa.

2. Mira atrás

Mirar hacia atrás es similar. Podemos usar? <= Para una mirada positiva hacia atrás y?

.*(?<=program)creek.*

partidos de programcreek
softwarecreek no coincide

Categorías
Regular Expressions

Referencias inversas en expresiones regulares de Java

Las referencias inversas en las expresiones regulares de Java son otra característica importante proporcionada por Java.

Comprender backreferences, necesitamos entender grupo primero. Agrupar en expresión regular significa tratar varios caracteres como una sola unidad. Se crean colocando los caracteres que se van a agrupar dentro de un paréntesis – ”()”. Cada conjunto de paréntesis corresponde a un grupo.

Las referencias inversas son convenientes, porque nos permite repetir un patrón sin volver a escribirlo. Podemos simplemente referirnos al grupo definido previamente usando # (# es el número de grupo). Esto tendrá más sentido después de leer los dos ejemplos siguientes.

Ejemplo 1: encontrar un patrón repetido

( d d d) 1 coincide con 123123, pero no coincide con 123456 en una fila. Esto indica que el patrón referido debe ser exactamente el nombre.

String str = "123456";
Pattern p = Pattern.compile("(ddd)1");
Matcher m = p.matcher(str);
System.out.println(m.groupCount());
while (m.find()) {
	String word = m.group();
	System.out.println(word + " " + m.start() + " " + m.end());
}

1
123123 0 6

Ejemplo 2: encontrar palabras duplicadas

String pattern = "b(w+)b[wW]*b1b";
Pattern p = Pattern.compile(pattern, Pattern.CASE_INSENSITIVE);
String phrase = "unique is not duplicate but unique, Duplicate is duplicate.";
Matcher m = p.matcher(phrase);
while (m.find()) {
	String val = m.group();
	System.out.println("Matching subsequence is "" + val + """);
	System.out.println("Duplicate word: " + m.group(1) + "n");
}

La subsecuencia coincidente es «única, no duplicada, sino única»
Palabra duplicada: única

La subsecuencia coincidente es «El duplicado es duplicado»
Palabra duplicada: duplicada

Nota: Este no es un buen método para usar expresiones regulares para encontrar palabras duplicadas. En el ejemplo anterior, el primer «duplicado» no coincide.

¿Por qué utilizar referencias inversas?

Vea más ejemplos de expresiones regulares.

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.

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

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.

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.