Bloque de expresiones regulares (RegExp)
Empezamos el bloque de expresiones regulares:
📗 ¿Qué son las expresiones regulares?📗
📌 ️ — El término de expresiones regulares nace a partir del término inglés Regular Expressions. Del que también surgen varias abreviaturas como regEx (de REGular EXpressions) o regExp (de REGular EXPressions).
Las expresiones regulares RegEx, no son un lenguaje de programación, sino una serie de símbolos (expresiones o patrones) que nos permitirán definir patrones de búsqueda en cadenas de texto.
Por tanto, no son nada más y nada menos que un lenguaje para manipular/realizar búsquedas sobre archivo de texto o simplemente sobre textos sin la necesidad de que estos estén contenidos en el interior de un fichero.
Si os pasa como al niño de “En ocasiones veo muertos” cuando veis unas expresiones regulares y se os iluminan los ojos🥺 o entráis en modo pánico 😲
¡Ya no tenéis porque preocuparos! Ya que os aseguro que después de ver este apartado, cuando veáis una regex ya no os sucederá.
📗 ¿Para qué sirven las expresiones regulares?📗
No todas las versiones de regex son iguales ya que existen distintos motores (engines) para trabajar con regex. Algunos de los principales engines de regex son:
✽ .NET (C#, VB.NET etc.)
✽ PCRE (C, PHP, R…)
✽ Perl → basado en el PCRE2 engine
✽ Python
✽ Ruby 2+
📌 ️ — En el caso de VSC trabajamos con la versión de .NET
📗 ¿Para qué sirven las expresiones regulares?📗
Regex nos sirve para múltiples funciones, entre las que se encuentran:
- Realizar validaciones: tanto en HTML, como en lenguajes de programación como Java, C#, Python, JavaScript…
- Realizar búsquedas: dentro de un documento.
- Substituir contenido de forma masiva: evitando tener que realizar sustituciones una a una con la pérdida de tiempo que esto supondría.
Un ejemplo de ello, podría ser realizar la edición de archivos CSV, que usualmente van separados por ejemplo por un punto y coma:
O, incluso, realizar substituciones masivas dentro de un INSERT múltiple en SQL.
📗¿Qué es el patrón?📗
El patrón, es la expresión mediante el cual intentamos hacer match en Regex. Es decir, lo que vamos a buscar.
📗 ¿Qué es hacer match en Regex?📗
El match en Regex se produce cuando tras analizar el resultado de un patrón, se pueden encontrar uno o varios casos en los que si que se cumple dicha condición dentro del documento. ¡Por tanto, solamente cuando encontramos casos!
Vamos a ver un ejemplo de match. Basándonos en el siguiente texto para realizar la búsqueda:
123
234
123456
1234567
Aunque ahora explicaremos como abrir el buscador, para trabajar con reggex es muy importante que marquemos el siguiente símbolo:
Y si queremos que cuando realicemos una búsqueda sea keysensitive, es decir que distinta mayúsculas y minúsculas marcaremos lo siguiente:
Si queremos seleccionar solamente las cadenas de texto que tengan 234 haríamos lo siguiente:
En este caso en concreto, si nos fichamos hemos realizado 3 match en 3 líneas de las 4 que tenemos:
Podemos realizar más de un match en una misma línea. Vamos a ver un ejemplo:
123
234
123456123456
1234567
📗 Plugins para trabajar con regex en Visual Studio Code 📗
Los plugins que instalaremos para trabajar con regex serán:
- Reg-visualizer: nos explicará el patrón regex que hayamos definido de una forma muy visual. Para instalarlo hacemos lo siguiente:
Para abrirlo el plugin existen varias maneras pero la más sencilla es seleccionar un texto de una sola línea cualquiera, pulsar botón derecho e ir a RegExp Visualize:
Vamos a ver un ejemplo:
Una vez abierto, lo podéis utilizar para ayudaros a entender otras expresiones regulares con solo cambiar el patrón que hay dentro del input.
Este plugin será un plugin imprescindible para aprender que hace una expresión regex.
📗 Presentado la * “de Kleene” 📗
/*
Cualquier carácter (incluido el salto de línea\n
)
📌 ️ — El
*,
también es conocido como la “estrella de Kleene”. Ya que, para gran parte de la comunidad, Kleene por decirlo de alguna manera ha sido el “padre” de las expresiones regulares. Y como pequeño homenaje la comunidad de desarrolladores asocia la expresión que lo engloba todo, el carácter * a su nombre.
Basándonos en este mensaje que tiene 3 líneas:
- La primera línea vemos que contiene texto además de un salto de línea.
- La segunda línea podemos ver que tiene dos espacios y además también contiene otro salto de línea
- Y finalmente, la tercera línea contiene un solo espacio, pero al no haber más líneas no contiene ningún salto de línea.
Si realizamos \n
podemos ver los distintos saltos de línea que hay en nuestro documento:
Y confirmar que tenemos solamente dos saltos de líneas en nuestro documento.
Si utilizamos \s
o en su defecto escribimos un espacio donde la \s
sin nada más, podemos ver que hacemos un match de todos los espacios del documento:
En cambio, si utilizamos la estrella de Kleene, podemos ver que se seleccionan todos los caracteres inclusive los saltos de línea y espacios:
📌 ️ — Nota: Por ello, decimos que la estrella de Kleene lo engloba todo incluso los saltos de línea o espacios.
📗Single Characters📗
En esta sección vamos a aprender principalmente determinados caracteres. ¡Vamos a ello!
Para buscamos un carácter o conjunto de caracteres podemos realizar lo siguiente:
ojo cojo ojimetro
ojo con el perro
ojeando el metro
Si queremos seleccionar solamente un carácter podemos escribir dicho carácter en el buscador:
Si queremos buscar varios caracteres consecutivos:
[carácter/es]
buscará cualquier carácter que este dentro de los[]
. Si os fijáis, la doble rr de perro también hace match con este tipo de expresiones:
ojo cojo ojimetro
ojo con el perro
ojeando el metro
📌 ️ — Por lo que, si os fijáis, cuando usamos [ro]
se están seleccionando todos los caracteres que sean r
o o
. Independientemente de si son caracteres consecutivos o no. Frente al ejemplo anterior, en el que no utilizamos los []
y solamente se seleccionaban los caracteres que son seguidos como por ejemplo perro
o metro
pero no la o de o
jo
.
[^carácter/es]
realizará el match con cualquier carácter que NO esté dentro de los[]
independiente de si es consecutivo o si no.
ojo cojo ojimetro
ojo con el perro
ojeando el metro
Si os fijáis, es justamente lo contrario que la expresión que acabamos de ver en el ejemplo anterior:
[a-z]
Nos permite hacer match de un rango en específico.
abcdefghijklmnñopqrstuvwxyzABCDEFGHIJKLMNÑOPQRSTUVWXYZ
Si nos fijamos, solamente se seleccionan los carácter en minúsculas entre estos. La ñ habría que ponerla a parte entre los [] si queremos que se incluya.
[a-zñ]
Si quisiéramos añadir también la ñ también u otro carácter al rango realizaríamos lo siguiente:
abcdefghijklmnñopqrstuvwxyzABCDEFGHIJKLMNÑOPQRSTUVWXYZ
[a-zñA-ZÑ]
Si quisiéramos añadir las mayúsculas y las minúsculas (con la ñ en minúscula y la Ñ en mayúsculas) realizaríamos lo siguiente:
abcdefghijklmnñopqrstuvwxyzABCDEFGHIJKLMNÑOPQRSTUVWXYZ
[1-9]
También podemos utilizar rangos de números:
123456789
🚨IMPORTANTE🚨, Si queremos también incluir el 0 debemos empezar desde dicho número:
0123456789
[13579]
O inclusive definir un rango personalizado:
123456789
[^A-ZÑa-zñ]
Aunque si queremos identificar los caracteres que son numéricos dentro de un documento lo podemos hacer la siguiente manera:
1a2b3c4d5e6
Si quisiéramos hacer justamente lo contrario, podríamos hacer lo siguiente:
.
Selecciona cualquier carácter… ¡A excepción de los saltos de línea! Por lo que es casi igual de potente que la estrella de Kleene ¡Casi!
ojo cojo ojimetro
ojo con el perro
ojeando el metro
El primer uso que podríamos con .
sería el de seleccionar todos los caracteres del documento:
Pero si nos fijamos, tal y como hemos comentado, podemos ver que los saltos de línea no se seleccionan:
carácter/es . carácter/es
Aunque el uso más habitual del.
no es el anterior, sino el utilizarlo como una especie de “carácter comodín” de un solo carácter. Con la intención de poder hacer match sobre varios elementos a la vez. Vamos a verlo:
ojo loro rioja hoja
.. carácter/es
Otra alternativa para.
es añadir varios puntos a la vez..
:
ojo loro rioja hoja
También es habitual utilizarlo para seleccionar varios caracteres combinador con la famosa estrella de Kleene *
:
abcdefghijklmnñopqrstuvwxyzABCDEFGHIJKLMNÑOPQRSTUVWXYZ
Ya que seleccionar de esta manera el texto, nos permitirá seleccionar todo el texto hasta el final de la línea para por ejemplo reemplazar dicho contenido:
O inclusive añadir elementos. Vamos a ver un ejemplo de cómo añadir una ñ a este abecedario que no la contiene:
abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNÑOPQRSTUVWXYZ
La forma más sencilla de hacer esto es la siguiente:
Aunque existe otra forma de coger un bloque vamos a ver un ejemplo. Aunque, nos detendremos en ello más adelante durante a lo largo del curso. Vamos a verlo:
\char
En ciertas ocasiones nos puede ser difícil seleccionar un carácter determinado como por ejemplo solamente los puntos o las barras laterales. Para ello, debemos realizarlo lo siguiente:
hola@gmail.com
Si intentamos seleccionar solamente los puntos sin utilizar la contrabarra, podemos ver que, en este caso, nos seleccionaría todo el contenido:
Otro ejemplo podría ser el siguiente:
\@ezgj
Ya que, si utilizamos solamente una contra barra, podemos ver que VSC nos muestra una advertencia avisándonos que la expresión regular no es correcta:
📗Characters Classes📗
En este apartado, vamos a ver principalmente en como trabajar principalmente en la búsqueda de caracteres por tipo: espacios, dígitos, etc.
\w
Con la w en minúsculas seleccionamos cualquier carácter de una palabra que sea un número o una letra (a excepción de la ñ)
¡Hola desde Regex!
123 jkljlk .... @ as *``´¨
eñe
Si queremos añadir también la ñ (solamente en minúsculas) realizaríamos lo siguiente:
¡Hola desde Regex!
123 jkljlk .... @ as *``´¨
eñe
Si nos fijamos, podemos ver que \w
es equivalente [a-zA-Z0-9)]
¡Hola desde Regex!
123 jkljlk .... @ as *``´¨
eñe
Y si queremos incluir la ñ también podemos realizar lo siguiente:
Su equivalencia sería [a-zñA-ZÑ0-9)]
:
\W
Con la W en mayúsculas, seleccionamos cualquier carácter que no sea de una palabra
¡Hola desde Regex!
123 jkljlk .... @ as *``´¨
eñe
También podríamos utilizar a equivalente [^a-zA-Z0-9]
\d
Con la d en minúsculas, seleccionamos cualquier digito decimal.
1a2b3c4d5e6
Sería equivalente a utilizar [0-9]
:
\D
Con la D en mayúsculas, seleccionamos cualquier digito que no sea un número decimal.
1a2b3c4d5e6
Sería equivalente a utilizar [^0-9]
\s
Con la s en minúscula, seleccionamos cualquier carácter que sea un espacio
1a 2b 3c 4d 5e 6
\S
Con la S en mayúsculas, seleccionamos cualquier carácter que no sea un espacio:
1a 2b 3c 4d 5e 6
\b
en minúscula, nos permite seleccionar el límite de una palabra, es decir, el inicio y el final de dicha palabra:
ojo cojo ojimetroojo con el perroojeando el metro
\n
como ya hemos visto anteriormente nos permite mostrar los saltos de línea:
ojo cojo ojimetroojo con el perroojeando el metro
📗Quantifiers📗
Los cuantificados especifican con que frecuencia debe coincidir una expresión regular o parte de ella.
AB
A_B
A__B
A___B
A____B
Si nosotros hacemos lo siguiente, estamos buscando las búsquedas que tengan literalmente A_B:
Pero ¿Cómo haríamos si quisiéramos seleccionar todos los elementos que tengan AB los que tengan barras bajas de por medio y los que no? Vamos a verlo:
*
nos permite definir que intentemos hacer coincidir el patrón que hemos definido previamente cero o más veces. Vamos a ver un ejemplo:
AB
A_B
A__B
A___B
A____B
Si nos fijamos, estamos seleccionado todos, ya que con el * sin nada más le estamos especificando que nos seleccioné todos los elementos ya tenga 0, 1 o muchas coincidencias.
?
nos permite definir que intentemos hacer coincidir el patrón que hemos definido previamente cero o una vez. Vamos a ver un ejemplo:
AB
A_B
A__B
A___B
A____B
+
nos permite definir que intentemos hacer coincidir el patrón que hemos definido previamente una o más veces. Vamos a ver un ejemplo:
{n}
nos permite indicar que el patrón debe coincidir exactamente las veces que le indiquemos entre paréntesis. Vamos a ver un ejemplo:
{n,}
nos permite indicar que el patrón debe coincidir las veces que le indiquemos entre paréntesis o más, es decir, sería algo así como un como mínimo. Vamos a ver un ejemplo:
{n,m}
nos permite indicar que el patrón debe de repetirse tantas entre N y M. Vamos a ver un ejemplo:
Greedy = ‘Codicioso’ significa que coincide intentando coger la cadena más larga posible.
Suponiendo que tenemos el siguiente texto:
stackoverflow
Con el greedy (el codicioso) queremos llegar a la cadena más larga posible:
Podemos ver que llegamos hasta la o más lejana de todas.
Lazy = ‘Perezoso’ significa que coincide intentando coger la cadena más corta posible.
Suponiendo que tenemos el siguiente texto:
stackoverflow
Con el lazy (el perezoso) queremos acabar cuanto antes, por lo que cogemos la cadena más corta posible:
📗Anchors Expressions📗
^
El patrón empieza por …
Vamos a ver un ejemplo que utilizaríamos para hacer match solamente los caracteres que empiecen por abc:
abc
bcde
cdefg
defghi
El patrón sería el siguiente:
$
El patrón acaba con…
abc
bcde
cdefg
defghbc
Si queremos seleccionar las cadenas de texto que acaban pro bc, el regex para hacer el match sería el siguiente:
\b
en minúsculas, nos seleccionar la posición previa a la primera letra de una palabra, y también, la posición posterior a la última letra de una palabra
StackOverflow
Supercalifragilisticoespialidoso
Si reemplazamos el contenido actual, podemos confirmar que no seleccionar las letras, sino que justo el carácter de antes y de después:
\bstring\b
en minúsculas, nos permite seleccionar solamente las palabras que sean literalmente la que habíamos visto. Vamos a ver un ejemplo:
StackOverflow
StackOverflower
Supercalifragilisticoespialidoso
En cambio, si hiciéramos lo mismo realizando la búsqueda normal y corriente, podemos ver que se seleccionan las dos:
Y en este caso, solamente queríamos seleccionar las palabras que fueran así de inicio a fin.
Vamos a ver otro ejemplo:
44 hojas de A4
\bstring
ostring\b
su uso más habitual es para identificar si una palabra empieza o acaba por un determinado
O incluso podemos a llegar hasta a hacer que un carácter empiece por 4 comodín y acabe por 4. Vamos a verlo:
\Bstring\B
en mayúsculas, nos permite buscar una coincidencia que NO está al inicio o al final de la palabra. Vamos a ver un ejemplo:
Tengo un 4x4
Por tanto, \b
y \B
literalmente la noche y el día, justamente lo contrario.
📗 Alternation📗
|
nos permite seleccionar varias opciones dentro de nuestro patrón para hacer match:
123
234
123456123456
1234567
Por ejemplo, en este caso, estamos buscando los números 23 y/o 56:
Pero si buscásemos dos números y uno o los dos no existiría el otro continuaría mostrándose sin problema. Vamos a verlo:
📗 Capturing groups 📗
()
podemos definir agrupaciones mediante a grupos de la siguiente manera:
aA
bB
()|()
o incluso trabajar con varios grupos de la siguiente manera:
Es recomendable trabajar con grupos debido a que nos permitirán reemplazar contenido de una forma sencilla.
También podemos añadir condiciones en regexp vamos a verlos:
(? (A)Yes)
Si el patrón definido dentro del bloque A hace match, entonces, busca también el patrón YES
buenos días
Vemos que si existe el primer bloque A (en este caso el valor buenos acompañado de un espacio), también se selecciona buenos días:
En cambio, si no existe el primer bloque A (en este caso el valor test y un espacio), no se seleccionará nada:
(? (A)Yes|No)
Si el patrón definido dentro del bloque A hace match, entonces, busca también el patrón YES o NO.
buenos días
buen día
buenas tardes
buena tarde
(? (A)B|C|D)
Aunque también podríamos anidar más elementos sin problema de la siguiente manera:
buenos días
buen día
buenas tardes
buena tarde
buenas noches
📗 Substitution or String remplacement 📗
Bueno, ahora que ya estamos acabando, vamos a meterle “una pizca de sal” a las expresiones regulares viendo cómo funciona el reemplazo de solamente ciertas partes de un match.
()
cuando queremos realizamos substituciones con string remplacement es muy importante (ya que es totalmente necesario) el trabajar con agrupaciones. Vamos a ver un ejemplo:
152
15
75
Imaginaros que ejemplo hemos introducido erróneamente los precios de unos registros en la base de datos sin la parte decimal y estos deberían de tener dos dígitos a 00 o a su correspondiente valor. Primeramente, debemos seleccionarlos:
Bien, una vez seleccionamos queremos reemplazarlos. Para ello, utilizamos un $
seguido del número del grupo (lo explicaremos en el siguiente punto más detalladamente). Primero quiero que entendáis el concepto de porque utilizamos grupos. Si intentamos hacer un remplazo con $1 añadiéndoles la coma junto a dos dígitos (en este caso dos ceros) $1.00:
Podemos ver que el texto se modifica por $1.00:
Y esto no es lo nosotros tenemos pensado hacer, ya que nosotros queremos mantener el valor actual de cada registro 152,15 y 75. Pero añadiendo su parte decimal 152.00, 15.00 y 75.00. Pero ¿Por qué sucede esto? El tema es que con $1 seleccionamos grupos y por tanto, si no tenemos grupos, regex no sabe a que nos estamos refiriendo y se imagina que es un texto que le queremos pasar y lo añade sin más.
Vamos a ver como solucionar esto:
Y ahora sí, el resultado es el deseado:
$n
Si queremos reemplazar una parte del texto sobre el que hemos hecho match, podemos utilizar el símbolo de $ acompañado del grupo del patrón que queremos reemplazar. Vamos a ver un ejemplo:
malos días
malas noches
Existe la posibilidad de trabajar con varios grupos a la vez. Por ejemplo, en este ejemplo, vamos a invertir el nombre y el apellido:
Bob, Smith
Green, Mel
Sam, Jones
Black, Liz
White, Tim
Para ello, primeramente hacemos el match de los valores:
Y posteriormente modificamos cuando reemplazamos le indicamos que queremos poner el bloque 2 donde actualmente está el bloque 1, añadir una coma y un espacio y, posteriormente, añadir el bloque 1 donde actualmente está el bloque 2:
El resultado será el siguiente:
Existe una web que explica esto muy bien. Y que nos puede ayudar a entender el concepto de los grupos mucho mejor. La web se llama regex101. Si vamos a dicha web y trasladamos nuestro ejemplo, podemos ver los distintos grupos que tenemos actualmente de una forma muy visual:
Al final, lo que hemos hecho son $2 $1 no es nada más y nada menos que un cambio de cromos.
También podemos basarnos en grupos para añadir información. Vamos a ver un ejemplo:
1a 2b 3c 4d
Primeramente, antes de todo hacemos match:
Una vez tenemos el match hecho, vamos a realizar lo siguiente:
Tras pulsar el botón de replace all vemos que el resultado será el siguiente:
También es habitual utilizar substituciones para eliminar caracteres repetidos. Vamos a ver un ejemplo:
Esa era era la respuesta respuesta correcta.
Basándonos en el siguiente patrón regexp:
Podemos ver que estamos buscando las palabras que se repiten una o más veces con un espacio:
Tras darle a reemplazar vemos que se ha modificado correctamente:
También podemos trabajar con varios grupos y mediante al número que acompaña al $ le indicamos al patrón que grupo vamos a coger:
Hay que matizar muy bien lo que realmente queremos hacer dentro de un bloque. Para entender esto mejor, vamos a ver un ejemplo con $2 (ya que estamos trabajando sobre el segundo bloque) en el que queremos añadir test delante de la palabra:
abc123
Podemos confirmarlo si vamos a la web regex101 podemos ver que dentro del grupo también tenemos submatches que, aunque todos forman parte del bloque/grupo, cada uno es un submatch distinto dentro del match/bloque principal:
El resultado una vez pulsemos sobre remplace all será el siguiente 1test 2test 3test. Vamos a verlo:
Si quisiéramos darle la vuelta a la tortilla y que fuera test1, test2 y test3 haríamos lo siguiente:
1. HTML
2. CSS
3. JS
(?<groupName1>exp),(?<groupName2>exp)$
existe la posibilidad de utilizar nombre para bautizar a los grupos. Su principal utilizar es dar un tip (pista) de lo que contiene dicho grupo.
🚨En algunos motores de expresiones regulares permiten realizar substituciones con $groupName. Aunque, desgraciamente, en el caso del motor utilizado en VSC no es compatible con ello.🚨
Vamos a ver un ejemplo:
1a_2b_3c
$&
es una referencia especial que se utiliza en el contexto de la sustitución de texto para hacer hacer referencia a la coincidencia completa encontrada por la expresión regular.
Cuando se utiliza $&
en la cadena de reemplazo, se sustituye por la coincidencia completa encontrada por la expresión regular. Es decir, se reemplaza por el texto que coincide con el patrón de la expresión regular.
Vamos a ver un ejemplo:
GrupoI, grupoII, grupoIIIGrupoI, grupoII, grupoIII
Observad en el siguiente ejemplo como no es necesariamente obligatorio que el texto a substituir debe de estar formado por distintos grupos:
Texto de ejemplo
📗 Back reference 📗
\1
nos permite seleccionar las referencias anteriores (o back references) nos permiten buscar si el mismo texto que hizo match, se encuentra otra vez dentro del documento. Vamos a ver unos ejemplos:
1a1
22a22
333a333
Si hacemos lo siguiente:
Podemos observar que estamos seleccionando el número que vaya acompañado de un carácter a y posteriormente se vuelva a repetir el primer número.
\groupName
de la misma forma que con \1 hemos seleccionado el grupo. También, podemos utilizar \k<groupName> para hacer una back reference hacía un grupo sobre el que ya hemos realiza un match. Vamos a verlo:
112233445566
📗 Non capturing groups📗
Son grupos que se utilizan dentro del patrón de las expresiones regulares pero que no se capturan (non-capturing groups) y por tanto, a diferencia de los grupos normales, estos no se almacenan como una entidad separada en el resultado.
Aquí hay algunas razones por las cuales los grupos sin captura son útiles:
- Modificadores o cuantificadores: Los grupos sin captura permiten aplicar modificadores o cuantificadores a un grupo de subpatrones sin afectar la estructura de los grupos de captura. Esto es útil cuando deseas aplicar una modificación o repetición a un conjunto de subpatrones sin tener que acceder a ellos individualmente en el resultado.
- Alternativas: Los grupos sin captura se utilizan para agrupar múltiples opciones dentro de una expresión regular. Esto permite especificar alternativas de forma concisa sin crear grupos de captura adicionales innecesarios.
- Claridad y legibilidad: Al utilizar grupos sin captura, puedes indicar explícitamente que no estás interesado en capturar o utilizar el texto coincidente de ese grupo en particular. Esto mejora la claridad y legibilidad del patrón, especialmente en casos donde hay múltiples grupos en juego.
- Mejor rendimiento: En algunas implementaciones de expresiones regulares, el uso de grupos sin captura puede ofrecer un mejor rendimiento, ya que no requieren el costo adicional de almacenar y mantener el texto coincidente como grupos separados.
En resumen, los grupos sin captura son útiles cuando deseas agrupar subpatrones juntos para aplicar modificadores, especificar alternativas o mejorar la claridad del patrón, sin la necesidad de capturar o almacenar el texto coincidente como grupos separados.
(?:exp)
En este caso, permite no capturar el grupo centrar . Vamos a verlo basado en este ejjemplo:
Hola, mi número es 0
Hola, mi dirección es 58
Vemos que tenemos 3 colores distintos:
Pero realmente tenemos dos grupos y no 3. Ya que la parte central no es un grupo:
Si por ejemplo hacemos un $1$2 para substituir los grupos fijaros en que se modifican:
Las construcciones (?!exp)
y (?=exp)
son conocidas como "lookahead" en expresiones regulares y tienen comportamientos opuestos. Con “lookahead”, nos referirnos en particular a mirar hacía el futuro, es decir, al proceso de anticiparse.
Basándonos en el siguiente texto:
este texto es un ejemplo. Para que se subraye, este texto no debe ir precedido de esto.
Vamos a ver las diferencias entre estos dos lookaheads (anticipaciones):
(?!exp)
, llamado "negative lookahead" (anticipación negativa), busca un punto de coincidencia en el cual la expresiónexp
NO se encuentra adelante. En otras palabras, coincide con el texto solo si no está seguido porexp
. Es una negación de lo que sigue.
(?=exp)
, llamado "positive lookahead" (anticipación positiva), busca un punto de coincidencia en el cual la expresiónexp
SÍ se encuentra adelante. En otras palabras, coincide con el texto solo si está seguido porexp
. Es una afirmación de lo que sigue.
(?<=exp)
, llamado "positive lookbehind", busca un punto de coincidencia en el cual la expresiónexp
SÍ se encuentra antes. En otras palabras, coincide con el texto solo si está precedido porexp
. Es una afirmación de lo que precede.
OpenAI es una empresa de IA ¡No se debe confundir OpenAI con closeAI!
(?<!exp)
, llamado "negative lookbehind", busca un punto de coincidencia en el cual la expresiónexp
NO se encuentra antes. En otras palabras, coincide con el texto solo si no está precedido porexp
. Es una negación de lo que precede.
📗 Hoja de resumen de expresiones regex 📗
📗Ejercicios y mejores webs:📗
Algunas webs con ejercicios regexp para practicar
- Ejercicios 1: Resuelve tantos ejercicios como puedas en: https://regexone.com/
- Ejercicio 2: https://regex.sketchengine.co.uk/
- Ejercicios 3: https://regexlearn.com/learn/regex101
Algunas webs importantes sobre Regexp:
- https://regexr.com/
- https://www.ocpsoft.org/tutorials/regular-expressions/java-visual-regex-tester/
- https://blog.robertelder.org/regular-expression-character-escaping/
- https://www.regular-expressions.info/tutorial.html
- https://www.rexegg.com/regex-quickstart.html
- http://w3.unpocodetodo.info/utiles/regex.php
Bueno… Ahora que ya sabemos RegExp ¡Que las expresiones regulares vayan con vosotros! Muchas gracias por la lectura ¡Saludos! 👋