JavaRush /Blog Java /Random-ES /RegEx: 20 breves pasos para dominar las expresiones regul...
Artur
Nivel 40
Tallinn

RegEx: 20 breves pasos para dominar las expresiones regulares. Parte 2

Publicado en el grupo Random-ES
RegEx: 20 breves pasos para dominar las expresiones regulares. Parte 1 Original aquí En la última parte dominamos las expresiones regulares más simples y ya hemos aprendido algo. En esta parte estudiaremos diseños un poco más complejos, pero créeme, no será tan difícil como podría parecer. RegEx: 20 breves pasos para dominar las expresiones regulares.  Parte 2 - 1Así que ¡continuemos!

Paso 8: estrella *y signo más+

RegEx: 20 breves pasos para dominar las expresiones regulares.  Parte 2 - 2Hasta ahora, más o menos sólo hemos podido hacer coincidir cadenas de una longitud determinada. Pero en los últimos problemas nos hemos acercado al límite de lo que podemos hacer con la notación que hemos visto hasta ahora. Supongamos, por ejemplo, que no estamos limitados a identificadores Java de 3 caracteres, sino que podemos tener identificadores de cualquier longitud. Una solución que pudo haber funcionado en el ejemplo anterior no funcionará en el siguiente ejemplo:
patrón: [a-zA-Z_$]\w\w 
cadena:   __e $12 3 3.2 fo Barra r a23 mm ab x
coincidencias: ^^^ ^^^ ^^^ ^^^  
( Ejemplo ) notaque cuando un identificador es válido pero tiene más de 3 caracteres, solo coinciden los primeros tres caracteres. Y cuando el identificador es válido, pero contiene menos de 3 caracteres, ¡la expresión regular no lo encuentra en absoluto! El problema es que las expresiones entre corchetes []coinciden exactamente con un carácter, al igual que las clases de caracteres como \w. Esto significa que cualquier coincidencia en la expresión regular anterior debe tener exactamente tres caracteres. Así que no funciona tan bien como esperábamos. *Los caracteres especiales y pueden ayudar aquí +. Estos son modificadores que se pueden agregar a la derecha de cualquier expresión para que coincida con esa expresión más de una vez. La estrella Kleene (o "asterisco") *indicará que la ficha anterior debe coincidir cualquier número de veces, incluidas cero veces. El signo más +indicará que necesita buscar una o más veces. Así, la expresión que precede +es obligatoria (al menos una vez), mientras que la expresión que precede *es opcional, pero cuando aparece, puede aparecer cualquier número de veces. Ahora, con este conocimiento, podemos corregir la expresión regular anterior:
patrón: [a-zA-Z_$]\w* 
cadena:   __e $123 3.2 fo Barr a23mm ab x 
coincidencias: ^^^ ^^^^ ^^ ^^^^ ^^^^^ ^^ ^ 
( Ejemplo ) ¡Ahora hacemos coincidir identificadores válidos de cualquier longitud! ¡Bingo! Pero ¿qué pasaría si usáramos ? +en lugar de *?
patrón: [a-zA-Z_$]\w+ 
cadena:   __e $123 3.2 fo Barr a23mm ab x
coincidencias: ^^^ ^^^^ ^^ ^^^^ ^^^^^ ^^ 
( Ejemplo ) Nos perdimos el último partido х. Esto se debe a que requiere +que coincida al menos un carácter, pero como la expresión entre paréntesis []anterior \w+ya se ha "comido" el carácter x, no hay más caracteres disponibles, por lo que la coincidencia falla. ¿ Cuándo podemos utilizar +? Cuando necesitamos encontrar al menos una coincidencia, pero no importa cuántas veces debe coincidir una expresión determinada. Por ejemplo, si queremos encontrar números que contengan un punto decimal:
patrón: \d*\.\d+ 
cadena:   0.011 .2 42 2.0 3.33 4.000 5 6 7.89012 
coincidencias: ^^^^^ ^^ ^^^ ^^^^ ^^^^^ ^^^^^^^  
( Ejemplo ) notaque al hacer que los números a la izquierda del punto decimal sean opcionales, pudimos encontrar 0,011 y 0,2. Para hacer esto, necesitábamos hacer coincidir exactamente un punto decimal con \.y al menos un dígito a la derecha del punto decimal con \d+. La expresión regular anterior no coincidirá con un número como 3., porque necesitamos al menos un dígito a la derecha del punto decimal para que coincida.

Como siempre, resolvamos un par de problemas sencillos:

Encuentre todas las palabras en inglés en el siguiente pasaje.
patrón:
cadena: 3 más 3 es seis pero 4 más tres es 7
coincidencias:    ^^^^ ^^ ^^^ ^^^ ^^^^ ^^^^^ ^^ 
( Solución ) Encuentre todos los símbolos de tamaño de archivo en la siguiente lista. Los tamaños de archivo consistirán en un número (con o sin punto decimal) seguido de KB, o MB:GBTB
patrón:
cadena:   11TB 13 14,4MB 22HB 9,9GB TB 0KB 
coincidencias: ^^^^ ^^^^^^ ^^^^^ ^^^  
( Solución )

Paso 9: signo de interrogación "opcional"?

RegEx: 20 breves pasos para dominar las expresiones regulares.  Parte 2 - 3¿Ya escribiste expresiones regulares para resolver el último problema? ¿Funcionó? Ahora intenta aplicarlo aquí:
patrón:
cadena: 1..3KB 5...GB ..6TB
partidos:  
Obviamente, ninguna de estas designaciones es un tamaño de archivo válido, por lo que una buena expresión regular no debería coincidir con ninguna de ellas. La solución que escribí para resolver el último problema coincide con todos ellos, al menos en parte:
patrón: \d+\.*\d*[KMGT]B 
cadena:   1..3KB  5...GB .. 6TB 
coincidencias: ^^^^^^ ^^^^^^ ^^^ 
( Ejemplo ) Entonces, ¿cuál es el problema? De hecho, sólo necesitamos encontrar un punto decimal, si lo hay. Pero *permite cualquier número de coincidencias, incluido cero. ¿Hay alguna manera de hacer coincidir solo cero veces o una vez? ¿Pero no más de una vez? Por supuesto que sí. "opcional" ?es un modificador que coincide con cero o uno de los caracteres anteriores, pero no más:
patrón: \d+\.?\d*[KMGT]B 
cadena: 1.. 3KB 5...GB .. 6TB 
coincidencias:     ^^^ ^^^ 
( Ejemplo ) Estamos más cerca de una solución aquí, pero esto no es exactamente lo que necesitamos. Veremos cómo solucionar este problema en unos pocos pasos un poco más adelante.

Mientras tanto, solucionemos este problema:

En algunos lenguajes de programación (por ejemplo, Java), algunos números enteros y de coma flotante (punto) pueden ir seguidos de l/ Ly f/ Fpara indicar que deben tratarse como long/float (respectivamente) en lugar de como int/double normal. Encuentre todos los números "largos" válidos en la siguiente línea:
patrón:
cadena:   13L largo 2l 19 L lL 0 
coincidencias: ^^^ ^^ ^^ ^ 
( Solución )

Paso 10: signo "o"|

RegEx: 20 breves pasos para dominar las expresiones regulares.  Parte 2 - 4En el paso 8, tuvimos algunas dificultades para encontrar los diferentes tipos de números de coma flotante:
patrón: \d*\.\d+ 
cadena:   0.011 .2 42 2.0 3.33 4.000 5 6 7.89012 
coincidencias: ^^^^^ ^^ ^^^ ^^^^ ^^^^^ ^^^^^^^  
El patrón anterior hace coincidir números con un punto decimal y al menos un dígito a la derecha del punto decimal. Pero ¿qué pasa si también queremos hacer coincidir cadenas como 0.? (No hay números a la derecha del punto decimal). Podríamos escribir una expresión regular como esta:
patrón: \d*\.\d* 
cadena:   0.011 .2 42 2.0 3.33 4.000 5 6 7.89012 0. . 
coincidencias: ^^^^^ ^^ ^^^ ^^^^ ^^^^^ ^^^^^^^ ^^ ^ 
( Ejemplo ) Esto coincide 0., pero también coincide con un solo punto ., como puede ver arriba. En realidad, lo que intentamos hacer coincidir son dos clases de cadenas diferentes:
  1. números con al menos un dígito a la derecha del punto decimal
  2. números con al menos un dígito a la izquierda del punto decimal
Escribamos las siguientes 2 expresiones regulares, independientes entre sí:
patrón: \d*\.\d+ 
cadena:   0.011 .2 42 2.0 3.33 4.000 5 6 7.89012 0. .
coincidencias: ^^^^^ ^^ ^^^ ^^^^ ^^^^^ ^^^^^^^  
patrón: \d+\.\d* 
cadena:   0.011 .2 42 2.0 3.33 4.000 5 6 7.89012 0. .
coincidencias: ^^^^^ ^^^ ^^^^ ^^^^^ ^^^^^^^ ^^ 
Vemos que en ninguno de estos casos las subcadenas , o 42son 5encontradas por el motor. Para obtener el resultado requerido no estaría de más combinar estas expresiones regulares. ¿Cómo podemos lograr esto? El signo "o" nos permite especificar varias secuencias posibles de coincidencias a la vez en una expresión regular. Así como el signo "o" nos permite especificar caracteres individuales alternativos, podemos especificar expresiones alternativas de varios caracteres. Por ejemplo, si quisiéramos buscar "perro" o "gato", podríamos escribir algo como esto: 6.|[]|
patrón: \w\w\w 
cadena:   Obviamente , un perro es mejor mascota que un gato .
coincidencias: ^^^^^^^^^ ^^^ ^^^^^^ ^^^ ^^^ ^^^ 
( Ejemplo ) ... pero esto coincide con todas las secuencias de caracteres triples de la clase "palabra". Pero "perro" y "gato" ni siquiera tienen letras en común, por lo que los corchetes no nos ayudarán aquí. Aquí está la expresión regular más simple que podríamos usar y que coincide con ambas y solo con estas dos palabras:
patrón: perro|gato 
cadena: Obviamente, un perro es mejor mascota que un gato .
coincidencias:               ^^^ ^^^ 
( Ejemplo ) El motor de expresiones regulares primero intenta hacer coincidir la secuencia completa a la izquierda del carácter |, pero si falla, intenta hacer coincidir la secuencia a la derecha del carácter |. |También se pueden encadenar varios caracteres para que coincidan con más de dos secuencias alternativas:
patrón: perro|gato|mascota 
cadena: Obviamente, un perro es mejor mascota que un gato .
coincidencias:               ^^^ ^^^ ^^^ 
( Ejemplo )

Ahora resolvamos otro par de problemas para comprender mejor este paso:

Utilice el signo |para corregir la expresión regular decimal anterior y producir un resultado como este:
patrón:
cadena:   0.011 .2 42 2.0 3.33 4.000 5 6 7.89012 0. .
coincidencias: ^^^^^ ^^ ^^^ ^^^^ ^^^^^ ^^^^^^^ ^^ 
( Solución ) Utilice signos |, clases de caracteres, "opcional" ?, etc. para crear una única expresión regular que coincida con números enteros y de punto flotante (punto), como se analiza en el problema al final del paso anterior (este problema es un poco más complicado, sí ;))
patrón:
cuerda:   42L 12 x 3.4f 6l 3.3 0F LF .2F 0. 
coincidencias: ^^^ ^^ ^^^^ ^^ ^^^ ^^ ^^^ ^^  
( Solución ) 20 pasos cortos para dominar las expresiones regulares. Parte 3 RegEx: 20 pasos cortos para dominar las expresiones regulares. parte 4
Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION