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 1

Publicado en el grupo Random-ES
El original de este artículo está aquí . Probablemente no exista demasiada teoría, y proporcionaré varios enlaces a material más detallado sobre expresiones regulares al final del artículo. Pero me pareció que comenzar a profundizar en un tema como las expresiones regulares sería mucho más interesante si existiera la oportunidad no solo de estudiar, sino también de consolidar inmediatamente el conocimiento completando pequeñas tareas en el camino. RegEx: 20 breves pasos para dominar las expresiones regulares.  Parte 1 - 1Empecemos. Normalmente, quienes se oponen al uso de expresiones regulares ('RegEx' o simplemente 'regex') en programación citan la siguiente cita, atribuida a Jamie Zawinski: "Algunas personas, cuando se enfrentan a un problema, piensan: 'Lo sé, usaré expresiones regulares'. .'" Ahora ellos tienen dos problemas". De hecho, utilizar expresiones regulares todavía no es ni buena ni mala idea. Y esto por sí solo no añadirá problemas ni solucionará ninguno de ellos. Es sólo una herramienta. Y cómo lo usas (correcto o incorrecto) determina los resultados que verás. Si intenta utilizar expresiones regulares, por ejemplo, para crear un analizador HTML, lo más probable es que experimente problemas . Pero si sólo desea extraer, por ejemplo, marcas de tiempo de algunas cadenas, probablemente estará bien. Para que te resulte más fácil dominar las expresiones regulares, he preparado esta lección que te ayudará a dominar las expresiones regulares desde cero en solo veinte breves pasos. Este tutorial se centra principalmente en los conceptos básicos de las expresiones regulares y profundiza en temas más avanzados sólo cuando sea necesario.

Paso 1: ¿Por qué utilizar expresiones regulares?

RegEx: 20 breves pasos para dominar las expresiones regulares.  Parte 1 - 2Las expresiones regulares se utilizan para buscar coincidencias en el texto utilizando patrones específicos (patrones). Usando expresiones regulares, podemos extraer fácil y simplemente palabras del texto, así como caracteres literales y meta individuales y sus secuencias que cumplan con ciertos criterios. Esto es lo que Wikipedia nos dice sobre ellas : Las expresiones regulares son un lenguaje formal para buscar y manipular subcadenas en el texto, basado en el uso de metacaracteres (caracteres comodín). Para la búsqueda se utiliza una cadena de muestra (patrón en inglés, en ruso a menudo se le llama "plantilla", "máscara"), que consta de símbolos y metasímbolos y que define la regla de búsqueda. Para manipular texto, se especifica adicionalmente una cadena de reemplazo, que también puede contener caracteres especiales. El patrón puede ser tan simple como la palabra dogde esta oración:
El veloz zorro marrón salta sobre el perro perezoso.
Esta expresión regular se ve así:
perro
...Bastante fácil, ¿no? El patrón también puede ser cualquier palabra que contenga la letra o. Una expresión regular para encontrar dicho patrón podría verse así:
\ Guau * _
( Puede probar esta expresión regular aquí ). Notará que a medida que los requisitos de "coincidencia" se vuelven más complejos, la expresión regular también se vuelve más compleja. Existen formas adicionales de notación para especificar grupos de caracteres y hacer coincidir patrones repetidos, que explicaré a continuación. Pero, tan pronto como encontramos una coincidencia con un patrón en algún texto, ¿qué podemos hacer con él? Los motores de expresiones regulares modernos le permiten extraer caracteres o secuencias de caracteres (subcadenas) del texto contenido, eliminarlos o reemplazarlos con otro texto. En general, las expresiones regulares se utilizan para analizar y manipular texto. Podemos extraer, por ejemplo, subcadenas que parecen direcciones IP y luego intentar verificarlas. O podemos extraer nombres y direcciones de correo electrónico y almacenarlos en una base de datos. O utilice expresiones regulares para encontrar información confidencial (como números de pasaporte o números de teléfono) en correos electrónicos y alertar al usuario de que puede estar poniéndose en riesgo. Regex es verdaderamente una herramienta versátil que es fácil de aprender pero difícil de dominar: "Así como hay una diferencia entre tocar bien una pieza musical y crear música, hay una diferencia entre conocer expresiones regulares y comprenderlas". - Jeffrey E. F. Friedl, Dominar las expresiones regulares

Paso 2: corchetes[]

Las expresiones regulares más simples y fáciles de entender son aquellas que simplemente buscan una coincidencia carácter por carácter entre el patrón de expresión regular y la cadena de destino. Intentemos, por ejemplo, encontrar un gato: RegEx: 20 breves pasos para dominar las expresiones regulares.  Parte 1 - 3
patrón: gato
Cadena: El gato se cortó cuando pasó debajo del auto.
coincidencias:      ^^^
( Cómo funciona en la práctica - ver aquí ) ¡NÓTESE BIEN! Todas las soluciones se presentan aquí únicamente como posibles soluciones. En las expresiones regulares, como en la programación en general, puedes resolver los mismos problemas de diferentes maneras. Sin embargo, además de una comparación estricta carácter por carácter, también podemos especificar coincidencias alternativas usando corchetes:
patrón: ca[rt]
Cadena: El gato se cortó cuando pasó debajo del auto.
coincidencias:      ^^^ ^^^
( Cómo funciona ) Los corchetes de apertura y cierre le indican al motor de expresiones regulares que debe coincidir con cualquiera de los caracteres especificados, pero solo con uno. La expresión regular anterior no encontrará, por ejemplo, la cartpalabra completa, sino que solo encontrará una parte de ella:
patrón: ca[rt]
cuerda: El gato fue cortado cuando corrió debajo del carro.
coincidencias:      ^^^ ^^^
( Cómo funciona ) Cuando utiliza corchetes, le indica al motor de expresiones regulares que coincida solo con uno de los caracteres contenidos entre corchetes. El motor encuentra el personaje c, luego el personaje a, pero si el siguiente personaje no es ro t, entonces no es una coincidencia completa. Si encuentra cay luego o ro t, se detiene. No intentará hacer coincidir más caracteres porque los corchetes indican que solo es necesario hacer coincidir uno de los caracteres contenidos. Cuando encuentra ca, busca ren la palabra siguiente carty se detiene porque ya ha encontrado una coincidencia para la secuencia car.

Objetivos de entrenamiento:

Escriba una expresión regular que coincida con los 10 patrones haden Hadeste extracto de juegos de palabras intraducibles en el dialecto local:
patrón:
cadena: Jim, donde Bill había tenido "había tenido" , había tenido "había tenido" . "Había tenido" había sido correcto.
coincidencias:                  ^^^ ^^^ ^^^ ^^^ ^^^ ^^^ ^^^ ^^^ ^^^ ^^^
( Ver posible solución aquí ) ¿Qué pasa con todos los nombres de animales en la siguiente oración?
patrón:
Cadena: Un murciélago, un gato y una rata entraron a un bar...
coincidencias:    ^^^ ^^^ ^^^
( Posible solución ) O incluso más simple: busque las palabras baro bat:
patrón:
Cadena: Un murciélago, un gato y una rata entraron a un bar...
coincidencias:    ^^^ ^^^
( Posible solución ) Ahora ya hemos aprendido a escribir expresiones regulares más o menos complejas, ¡y solo estamos en el paso 2! ¡Continuemos!

Paso 3: secuencias de escape

RegEx: 20 breves pasos para dominar las expresiones regulares.  Parte 1 - 4En el paso anterior, aprendimos sobre los corchetes []y cómo nos ayudan a encontrar coincidencias alternativas utilizando el motor de expresiones regulares. Pero ¿qué pasa si queremos encontrar coincidencias en forma de corchetes abiertos y cerrados []? Cuando quisimos encontrar una coincidencia carácter por carácter de la palabra cat, proporcionamos al motor de expresiones regulares esta secuencia de caracteres ( cat). Intentemos encontrar corchetes []de la misma manera:
patrón: [] 
cadena: ¡ No puedes hacer coincidir [] usando expresiones regulares! ¡Te arrepentirás de esto!
partidos: 
( Veamos qué pasó ) Sin embargo, algo no funcionó... Esto se debe a que los caracteres entre corchetes actúan como caracteres especiales del motor de expresiones regulares que generalmente se usan para indicar algo más, y no son un patrón literal para coincidir con ellos mismos. Como recordamos del paso 2, se utilizan para encontrar coincidencias alternativas para que el motor de expresiones regulares pueda hacer coincidir cualquiera de los caracteres contenidos entre ellas. Si no coloca ningún carácter entre ellos, puede provocar un error. Para hacer coincidir estos caracteres especiales, debemos escaparlos precediéndolos con un carácter de barra invertida \. La barra invertida (o barra invertida) es otro carácter especial que le indica al motor de expresiones regulares que busque el siguiente carácter literalmente, en lugar de usarlo como un metacarácter. El motor de expresiones regulares solo buscará caracteres [y, ]literalmente, si ambos están precedidos por una barra invertida:
patrón: \[\]
cadena: ¡No puedes hacer coincidir [] usando expresiones regulares! ¡Te arrepentirás de esto!
coincidencias:                  ^^ 
( Veamos qué pasó esta vez ) Bien, ¿qué pasa si queremos encontrar la barra invertida? La respuesta es simple. Dado que la barra invertida \también es un carácter especial, también es necesario utilizar un carácter de escape. ¿Cómo? ¡Barra invertida!
patrón: \\
cadena: C:\Users\Tanja\Pictures\Dogs
coincidencias:    ^ ^ ^ ^
( Mismo ejemplo en la práctica ) Sólo los caracteres especiales deben ir precedidos de una barra invertida. Todos los demás caracteres se interpretan literalmente de forma predeterminada. Por ejemplo, la expresión regular tliteralmente coincide solo tcon letras minúsculas:
patrón: t
cadena: tttt
coincidencias: ^ ^ ^ ^
( Ejemplo ) Sin embargo, esta secuencia \tfunciona de manera diferente. Es una plantilla para buscar un carácter de tabulación:
patrón: \ t
cadena: tttt
coincidencias:   ^ ^ ^
( Ejemplo ) Algunas secuencias de escape comunes incluyen \n(saltos de línea estilo UNIX) y \r(usados ​​en saltos de línea estilo Windows \r\n). \res un carácter de "retorno de carro" y \nun carácter de "avance de línea", los cuales se definieron junto con el estándar ASCII cuando los teletipos todavía se usaban ampliamente. Otras secuencias de escape comunes se cubrirán más adelante en este tutorial.

Mientras tanto, consolidemos el material con un par de sencillos acertijos:

Intente escribir una expresión regular para encontrar... una expresión regular;) El resultado debería ser algo como esto:
patrón:
cadena: ...¿hacer coincidir esta expresión regular ` \[\] ` con una expresión regular?
coincidencias:                       ^^^^	
( Solución ) ¿Lo lograste? ¡Bien hecho! Ahora intenta crear una expresión regular para buscar secuencias de escape como esta:
patrón:
cadena: ` \r `, ` \t ` y ` \n ` son todas secuencias de escape de expresiones regulares.
coincidencias:   ^^ ^^ ^^
( Solución )

Paso 4: busca "cualquier" carácter usando un punto.

RegEx: 20 breves pasos para dominar las expresiones regulares.  Parte 1 - 5Al escribir las soluciones de coincidencia de secuencias de escape que vimos en el paso anterior, es posible que se haya preguntado: "¿Puedo hacer coincidir el carácter de barra invertida y luego cualquier otro carácter que le siga?"... ¡Por supuesto que puede! Hay otro carácter especial que se utiliza para hacer coincidir (casi) cualquier carácter: el carácter de punto (punto). Esto es lo que hace:
patrón: .
cadena: Lo siento, Dave. Me temo que no puedo hacer eso.
coincidencias: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^	
( Ejemplo ) Si solo desea hacer coincidir patrones que parecen secuencias de escape, puede hacer algo como esto:
patrón: \\. 
cadena: Hola, Walmart, es mi nieto. Su nombre es " \n \r \t ".
coincidencias:                                              ^^ ^^ ^^	
( Ejemplo ) Y, como ocurre con todos los caracteres especiales, si desea hacer coincidir un literal ., debe anteponerlo con un carácter \:
patrón: \. 
cadena: La guerra es paz . Libertad es esclavitud . Ignorancia es fuerza . 
coincidencias:             ^ ^ ^
( Ejemplo )

Paso 5: rangos de caracteres

RegEx: 20 breves pasos para dominar las expresiones regulares.  Parte 1 - 6¿Qué pasa si no necesitas ningún símbolo, sino que solo quieres buscar letras en el texto? ¿O números? ¿O vocales? La búsqueda por clases de personajes y sus rangos nos permitirá conseguirlo.
` \n `, ` \r ` y ` \t ` son caracteres de espacio en blanco, ` \. `, ` \\ ` y ` \[ ` no son .	
Los caracteres son "espacios en blanco" si no crean una marca visible en el texto. Un espacio " " es un espacio, un salto de línea o una tabulación. Digamos que queremos encontrar secuencias de escape que representen solo caracteres de espacios en blanco \n, \ry \ten el pasaje anterior, pero no otras secuencias de escape. ¿Cómo podemos hacer esto?
patrón: \\[nrt] 
cadena: ` \n `, ` \r ` y ` \t ` son caracteres de espacio en blanco, ` \. `, ` \\ ` y ` \[ ` no son .
coincidencias:   ^^ ^^ ^^	
( Ejemplo ) Esto funciona, pero no es una solución muy elegante. ¿Qué pasa si más adelante necesitamos hacer coincidir la secuencia de escape para el carácter "avance de formulario" \f? (Este símbolo se utiliza para indicar saltos de página en el texto).
patrón: \\[nrt] 
cadena: ` \n `, ` \r `, ` \t ` y ` \f ` son caracteres de espacio en blanco, ` \. `, ` \\ ` y ` \[ ` no son .
coincidencias:   ^^ ^^ ^^	
( Solución que no funciona ) Con este enfoque, debemos enumerar por separado cada letra minúscula que queremos hacer coincidir, entre corchetes. Una forma más sencilla de hacer esto es utilizar rangos de caracteres para que coincidan con cualquier letra minúscula:
patrón: \\[az] 
cadena: ` \n `, ` \r `, ` \t ` y ` \f ` son caracteres de espacio en blanco, ` \. `, ` \\ ` y ` \[ ` no son .
coincidencias:   ^^ ^^ ^^ ^^	
( Y esto ya funciona ). Los rangos de caracteres funcionan como era de esperar, dado el ejemplo anterior. Coloque corchetes alrededor de la primera y la última letra que desee hacer coincidir, con un guión entre ellas. Por ejemplo, si solo desea buscar "conjuntos" de barras invertidas \y una letra de aa m, puede hacer lo siguiente:
patrón: \\[am] 
cadena: ` \n `, ` \r `, ` \t ` y ` \f ` son caracteres de espacio en blanco, ` \. `, ` \\ ` y ` \[ ` no son .
coincidencias:                         ^^	
( Ejemplo ) Si desea hacer coincidir varios rangos, simplemente colóquelos de un extremo a otro entre corchetes:
patrón: \\[a-gq-z] 
cadena: ` \n `, ` \r `, ` \t ` y ` \f ` son caracteres de espacio en blanco, ` \. `, ` \\ ` y ` \[ ` no son .
coincidencias:         ^^ ^^ ^^	
( Ejemplo ) Otros rangos de caracteres comunes incluyen: A-Zy0-9

Probémoslos en la práctica y resolvamos un par de problemas:

Los números hexadecimales pueden contener dígitos 0-9además de letras A-F. Cuando se utilizan para especificar colores, los códigos hexadecimales pueden contener un máximo de tres caracteres. Cree una expresión regular para buscar códigos hexadecimales válidos en la siguiente lista:
patrón:
cadena: 1H8 4E2 8FF 0P1 T8B 776 42B G12
coincidencias:      ^^^ ^^^ ^^^ ^^^	
( Solución ) Usando rangos de caracteres, cree una expresión regular que seleccione solo consonantes minúsculas (no vocales, incluida y) en la siguiente oración:
patrón:cadena 
: Las paredes en el centro comercial son totalmente , totalmente altas . _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
coincidencias:   ^ ^ ^^^ ^ ^^ ^ ^^ ^ ^ ^ ^^^ ^ ^ ^^^ ^ ^^	
( Solución )

Paso 6: símbolo "no", signo de intercalación, circunflejo, signo de intercalación...^

RegEx: 20 breves pasos para dominar las expresiones regulares.  Parte 1 - 7En verdad, hay más de 9000 nombres para este símbolo :) Pero, para simplificar, quizás nos centremos en "no". Mi solución al último problema es un poco larga. Se necesitaron 17 caracteres para decir "obtener el alfabeto completo excepto las vocales". Por supuesto que hay una forma más sencilla de hacerlo. El signo "no" ^nos permite especificar caracteres y rangos de caracteres que no deben coincidir con los especificados en el patrón. Una solución más sencilla al último problema anterior es encontrar caracteres que no representen vocales:
patrón : [ ^ aeiou ] cadena 
:   Las paredes del centro comercial son totalmente , totalmente altas . _ _ _ _ _ _ _ _ _ _ 
coincidencias: ^^ ^^ ^^^^ ^^^^ ^^ ^^^ ^ ^^ ^ ^^^^^^ ^ ^^^^^ ^^^ 	
( Ejemplo ) El signo "no" ^como el carácter más a la izquierda dentro de los corchetes []le indica al motor de expresiones regulares que coincida con un (cualquier) carácter que no esté entre corchetes. Esto significa que la expresión regular anterior también coincide con todos los espacios, puntos ., comas ,y mayúsculas Tal comienzo de una oración. Para excluirlos, también podemos ponerlos entre corchetes:
patrón : [ ^ aeiou . , T ] cadena  
: Las paredes del centro comercial son totalmente , totalmente altas . _ _ _ _ _ _ _ _ _ _ 
coincidencias:   ^ ^ ^^^ ^ ^^ ^ ^^ ^ ^ ^ ^^^ ^ ^ ^^^ ^ ^^	
( Ejemplo ) notaque en este caso no necesitamos escapar del punto con una barra invertida, como hicimos antes cuando lo buscamos sin usar corchetes. Muchos caracteres especiales entre corchetes se tratan literalmente, incluido el carácter de corchete de apertura [, pero no el de cierre ](¿puedes adivinar por qué?). El carácter de barra invertida \tampoco se interpreta literalmente. Si desea hacer coincidir una barra invertida literal \usando corchetes, debe escapar precediéndola con la siguiente barra invertida \\. Este comportamiento se diseñó para que los espacios en blanco también pudieran colocarse entre corchetes para hacer coincidir:
patrón: [\t]
cadena: tttt
coincidencias:   ^ ^ ^
( Ejemplo ) El signo "no" ^también se puede utilizar con rangos. Si quisiera capturar solo los personajes a, b, c, y , podría hacer algo como esto x:yz
patrón: [abcxyz] 
cadena:   abc defghijklmnopqrstuvw coincidencias xyz 
: ^^^ ^^^
( Ejemplo ) ...o podría especificar que quiero encontrar cualquier carácter que no esté entre dy w:
patrón: [^dw] 
cadena:   abc defghijklmnopqrstuvw coincidencias xyz 
: ^^^ ^^^
( Ejemplo ) Sin embargo,ten cuidadocon no" ^. Es fácil pensar "bueno, especifiqué [^ b-f], por lo que debería recibir una letra minúscula ao algo después de f. Ese no es el caso. Esta expresión regular coincidirá con cualquier carácter que no esté en ese rango, incluidas letras, números, puntuación y espacios.
patrón: [^dw] 
cadena:   abc defg h . i , j - klmnopqrstuvw xyz 
coincide: ^^^ ^ ^ ^ ^ ^^^
( Ejemplo )

Tareas de subida de nivel:

Utilice el signo "no" ^entre corchetes para hacer coincidir todas las palabras siguientes que no terminen en y:
patrón:
cadena: día perro cerdo pantano de heno bahía raya frotar 
coincidencias:      ^^^ ^^^ ^^^ ^^^	
( Solución ) Escriba una expresión regular usando un rango y un signo "no" ^para encontrar todos los años entre 1977 y 1982 (inclusive):
patrón:
cadena: 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984
coincidencias:            ^^^^ ^^^^ ^^^^ ^^^^ ^^^^ ^^^^
( Solución ) Escriba una expresión regular para encontrar todos los caracteres que no sean un carácter de signo "no" ^:
patrón:
cadena:   abc1 ^ 23*() 
coincidencias: ^^^^ ^^^^^	
( Solución )

Paso 7: clases de personajes

Las clases de caracteres son incluso más simples que los rangos de caracteres. Los diferentes motores de expresiones regulares tienen diferentes clases disponibles, por lo que aquí solo cubriré las principales. (Compruebe qué versión de expresiones regulares está utilizando, porque puede haber más, o pueden ser diferentes de las que se muestran aquí). Las clases de caracteres funcionan casi como rangos, pero no puede especificar los valores de 'inicio' y 'final':
Clase simbolos
\d "números"[0-9]
\w "símbolos de palabras"[A-Za-z0-9_]
\s "espacios"[ \t\r\n\f]
La clase de caracteres "palabra" \wes especialmente útil porque este conjunto de caracteres suele ser necesario para identificadores válidos (nombres de variables, nombres de funciones, etc.) en varios lenguajes de programación. Podemos usar \wpara simplificar la expresión regular que vimos antes:
patrón: \\[az] 
cadena: ` \n `, ` \r `, ` \t ` y ` \f ` son caracteres de espacio en blanco, ` \. `, ` \\ ` y ` \[ ` no son .
coincidencias:   ^^ ^^ ^^ ^^	
Usando \wpodemos escribir así:
patrón: \\\w 
cadena: ` \n `, ` \r `, ` \t ` y ` \f ` son caracteres de espacio en blanco, ` \. `, ` \\ ` y ` \[ ` no son .
coincidencias:   ^^ ^^ ^^ ^^	
( Ejemplo )

2 tareas para la suerte:

Como usted y yo sabemos, en Java, un identificador (nombre de una variable, clase, función, etc.) solo puede comenzar con la letra a- zA- Z, signo de dólar $o guión bajo _. ( el subrayado es, por supuesto, un mal estilo, pero el compilador lo omite, nota del traductor ). El resto de caracteres deben ser caracteres de "palabra" \w. Utilizando una o más clases de caracteres, cree una expresión regular para buscar identificadores Java válidos entre las siguientes secuencias de tres caracteres:
patrón:
cuerda:   __e $12 .x2 foo Barra 3mm
coincidencias: ^^^ ^^^ ^^^ ^^^	
( Solución ) Los números de Seguro Social (SSN) de EE. UU. son números de 9 dígitos en el formato XXX-XX-XXXX, donde cada X puede ser cualquier dígito [0-9]. Usando una o más clases de caracteres, escriba una expresión regular para encontrar SSN con el formato correcto en la siguiente lista:
patrón:
cadena: 113-25=1902 182-82-0192 H23-_3-9982 1I1-O0-E38B
coincidencias:              ^^^^^^^^^^^
( Solución ) RegEx: 20 pasos cortos para dominar las expresiones regulares. Parte 2. 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