Applying Regular Expressions
In this article you will find
- Introduction
- Example 1
- Example 2
- Example 3
- Example 4
In the last two editions of Coding Basics we learned about regular expressions, powerful tools for finding patterns in strings.
From document translation to Web Scraping, whenever you want to find specific information, RegEx is the most efficient way to perform these operations, saving us lines of code and mental effort in finding the right programming logic.
However, we have not yet seen examples where we can apply what we have learned. For this reason, in this post we will go over some examples of the use of regular expressions. This so that you know the reason why they are so important.
Let's get started!
Example 1
For this example we will do something simple. Here, we will design a program that:
- Convert all the text that we write in capital letters as long as the number of words does not exceed 500 characters.
For this we will have to use a method of the String class: This is upper(), which will convert all the text of a string to uppercase.
Also, we will use len to have the size of a list that we will create with all the characters.
But how do we convert the characters of a string into a list?
Easy, if we take into account what was explained in the previous chapters, we know that regular expressions have a special sequence r"\s", which matches whenever we have blank spaces, which separates one word from the other.
Also, yesterday we looked at the re package's own functions and we know that with split, we can use a specific character to separate words. Using all this, we will have:
import re
user_text = str(input('Write your text here'))
list_characters = re.split('\s', user_text)
if len(list_characters) > 500:
print('Sorry, you exceeded the word limit')
else:
print(user_text.upper())
print(list_characters)
As we can see, what we did was:
- Create an input for the user to place the text as a string.
- We use split to use spaces as separators and create a list with all the words.
- We use len to see if the size of the list (which has all the words) exceeds 500 elements.
So, testing the program:
>>> Write your text here
Hello, this has less than 500 words
HELLO, THIS HAS LESS THAN 500 WORDS
And for strings with more than 500 words:
>>> Write your text here
[Text with more than 500 words]
Sorry, you exceeded the word limit
Example 2
This second example will be based on filtering words. We will create a program that censors profanity and replaces it with a Bleep.
For this:
- We will ask the user for a text input of type string.
- We will use regular expressions to filter out bad words
- Finally, we'll write the string with bleeps instead of the cuss words.
To do this, we recall one of the functions from the re package, sub(), which allows us to replace matches with regular expression values by other characters. Following the syntax:
re.sub(regex, character_to_replace, string)
Now, if we want our regular expression to match only a complete word and not also the characters (That is, that there is a match with food, but not with the last three letters of good).
For this, we use the sequence \b at the beginning and end of the word, indicating that there will only be a match if it starts and ends that way. So:
r"\bHell\b"
However, we want more than one word to be filtered and also if we lowercase the first letter. For this, we use |, which acts as an "or", which allows us to add more matching words. So:
r"\bHell\b|\bhell\b"
And applying in the example for more than one bad word:
import re
user_text = str(input('Write your text here'))
regex = r"\bHell\b|\bhell\b|\bFuck\b|\bfuck\b|\bShit\b|\bshit\b"
curse_words = re.sub(regex, 'BLEEP', user_text)
print(curse_words)
Here, we can see that with sub we replace all these words with bleep in user_text. When executing:
>>> Write your text here
Fuck shit hell, what the hell I'm doing in this shit
BLEEP BLEEP BLEEP, What the BLEEP Im doing in this BLEEP
Example 3
For this example, we'll take a text-based role-playing approach, where we'll create a situation where we're asked for the password to get through a gate. This password will be knocked 3 times, neither more nor less.
To make this possible we will use findall, the re function that takes all the matches with a word/character of the regular expression and creates a list with all the results.
As for the regular expression, if we go back to the previous example, we want to take into account both upper and lower case at the beginning of the word. So:
r"\bKnock\b|\bknock\b"
And because findall will create a return list, we can create a conditional to see if the list size is equal to 3 or not. So:
import re
user_text = str(input('Welcome to the Society of Thieves from Gandorra\n Knock three times to use the society\'s password'))
knock = re.findall(r"\bKnock\b|\bknock\b", user_text)
if len(knock) == 3:
print("The gatekeeper has heard the password. You can pass.")
else:
print("The only thing that answers is the noise of a cricket.")
So, running the program:
Welcome to the Society of Thieves from Gandorra
Knock three times to use the society's password
knock knock knock
The gatekeeper has heard the password. You can pass.
And if there are more than three knocks:
Welcome to the Society of Thieves from Gandorra
Knock three times to use the society's password
knock knock knock knock
The only thing that answers is the noise of a cricket.
Example 4
For this last example, I want to test your knowledge of regular expressions by giving you a challenge.
What you should do is create a program that reads the following expression:
John is 24, Mary is 43, Dan is 26, Carla is 32
Then, using regular expressions, you must take the ages of each person and add them to get the total. As clues I will leave:
- \d Is a special sequence that can be used so that we have a match every time a number from 0 to 9 occurs in the string.
- int can be used to convert a number within a string to an integer
- findall allows us to get all the matches that match the regular expression.
That being said, the conditions are set for you to create your age addition program. Comment on the results obtained.
.
If you have found it difficult to get the result or if you want to see a way to fix it, pay attention to the following:
import re
text = 'John is 24, Mary is 43, Dan is 26, Carla is 32'
ages = re.findall(r'[\d][\d]', text)
ages = list(map(int, ages))
print(f'The sum of everyone\'s ages is {sum(ages)}')
How did we get to this?
Because \d only allows us to take a single digit from 0 to 9, we would take only one digit of the age. This is why we make use of the sets to obtain more than one character in the number through the following regular expression:
r"[\d][\d]"
So we can get matches with numbers like 24, 65, 79 or any combination of two digits. Now, in order to have all the ages in one place that we can control, we use findall. This allows us to pass all the ages to a list of strings that we will have to convert to an integer.
To convert a list from string to integers, we must use map, a function that acts somewhat like a for on elements such as lists.
What it will do is apply a specific function to each element of the iterable (in this case our list) and it will return all these results within a map type object. Map objects are iterables too and can be converted to other types of iterables using the list(), set(), etc... functions.
The map syntax would be as follows:
map(function, iterable)
So, we use int, which is a function that converts the content of an element to an integer, and we apply this to the list that findall created.
Finally, we add the ages. We do this by means of sum(), a function that allows us to add the value of all the elements of a list of integers. So, when running:
The sum of everyone's ages is 125
As you can see, regular expressions save us a lot of headaches, endless loops and conditionals. This is why they are so widely used in modern programming, saving us lines of code.
After this and the two previous posts, you will have a complete understanding of regular expressions and how to use them to your advantage, creating efficient programs that allow us to handle strings at a new level.
I look forward to seeing your next projects.
Thank you for your support and good luck!
Aplicando Expresiones Regulares
En este artículo encontrarás
- Introducción
- Ejemplo 1
- Ejemplo 2
- Ejemplo 3
- Ejemplo 4
En las últimas dos ediciones de Coding Basics aprendimos sobre las expresiones regulares, herramientas de gran potencial para encontrar patrones en strings.
Desde la traducción de documentos hasta el Web Scraping, siempre que quieras encontrar información específica, las RegEx son la forma más eficiente de realizar estas operaciones, ahorrándonos líneas de código y esfuerzo mental en encontrar la lógica de programación adecuada.
Sin embargo, todavía no hemos visto ejemplos donde podemos aplicar lo aprendido. Es por esto, que en este post iremos sobre algunos ejemplos del uso de las expresiones regulares. Esto para que conozcas la razón por la cual son tan importantes.
¡Comencemos!
Ejemplo 1
Para este ejemplo haremos algo sencillo. Aquí, diseñaremos un programa que:
- Convierta todo el texto que escribamos en mayúsculas siempre y cuando la cantidad de palabras no supere los 500 caracteres.
Para esto tendremos que usar un método propio de la clase String: Este es upper(), que convertirá todo el texto de una string en mayúscula.
Además, usaremos len para tener el tamaño de una lista que crearemos con todos los caracteres.
Pero ¿Cómo convertimos los caracteres de una string en una lista?
Fácil, si tenemos en cuenta lo explicado en los capítulos anteriores, sabemos que las expresiones regulares tienen una secuencia especial r"\s", la cual hace match siempre que tenemos espacios en blanco, cosa que separa una palabra de la otra.
Además, ayer vimos las funciones propias del paquete re y sabemos que con split, podemos usar un caracter específico para separar las palabras. Usando todo esto, tendremos:
import re
user_text = str(input('Write your text here'))
list_characters = re.split('\s', user_text)
if len(list_characters) > 500:
print('Sorry, you surpassed the word limit')
else:
print(user_text.upper())
print(list_characters)
Como vemos, lo que hicimos fue:
- Crear una input para que el usuario coloque el texto como string.
- Usamos split para usar los espacios como separadores y crear una lista con todas las palabras.
- Empleamos len para ver si el tamaño de la lista (que tiene todas las palabras) supera los 500 elementos.
Así, probando el programa:
>>> Write your text here
Hello, this has less than 500 words
HELLO, THIS HAS LESS THAN 500 WORDS
Y para strings con más de 500 palabras:
>>> Write your text here
[Text with more than 500 words]
Sorry, you surpassed the word limit
Ejemplo 2
Este segundo ejemplo se basará en filtrar palabras. Crearemos un programa que censure malas palabras y las reemplace por un Bleep.
Para esto:
- Le pediremos al usuario una entrada de texto de tipo string.
- Usaremos las expresiones regulares para filtrar las malas palabras
- Finalmente, escribiremos la string con bleeps en vez de las malas palabras.
Para llevar esto a cabo, recordamos una de las funciones del paquete re, sub(), la cual nos permite reemplazar los matches con los valores de las expresiones regulares por otros caracteres. Siguiendo la sintaxis:
re.sub(regex, character_to_replace, string)
Ahora, si queremos que en nuestra expresión regular coincida solo una palabra completa y no también los caracteres (Es decir, que haya match con food, pero no con las tres últimas letras de good).
Para esto, usamos la secuencia \b al principio y al final de la palabra, indicando que solo habrá match si empieza y termina de esa manera. Así:
r"\bHell\b"
Sin embargo, queremos que se filtre más de una palabra y que también lo haga si escribimos la primera letra con minúscula. Para esto, usamos |, que actua como un "or", lo cual nos permite agregar más palabras que hagan match. Así:
r"\bHell\b|\bhell\b"
Y aplicando en el ejemplo para más de una mala palabra:
import re
user_text = str(input('Write your text here'))
regex = r"\bHell\b|\bhell\b|\bFuck\b|\bfuck\b|\bShit\b|\bshit\b"
curse_words = re.sub(regex, 'BLEEP', user_text)
print(curse_words)
Aquí, podemos ver que con sub reemplazamos todas estas palabras por bleep en user_text. Al ejecutar:
>>> Write your text here
Fuck shit hell, What the hell Im doing in this shit
BLEEP BLEEP BLEEP, What the BLEEP Im doing in this BLEEP
Ejemplo 3
Para este ejemplo, tomaremos un enfoque de juegos de rol basados en texto, donde crearemos una situación en la que nos piden la contraseña para pasar por un portón. Esta contraseña será knock 3 veces, ni más ni menos.
Para que esto sea posible usaremos findall, la función de re que toma todos los matches con una palabra/caracter de la expresión regular y crea una lista con todos los resultados.
En cuanto a la expresión regular, si volvemos al ejemplo anterior, querremos tomar en cuenta tanto las mayúsculas como las minúsculas al principio de la palabra. Así:
r"\bKnock\b|\bknock\b"
Y debido a que findall creará una lista de regreso, podemos crear un condicional para ver si el tamaño de la lista es igual a 3 o no. Así:
import re
user_text = str(input('Welcome to the Society of Thieves from Gandorra\n Knock three times to use the society\'s password'))
knock = re.findall(r"\bKnock\b|\bknock\b", user_text)
if len(knock) == 3:
print("The gatekeeper has heard the password. You can pass.")
else:
print("The only thing that answers is the noise of a cricket.")
Así, ejecutando el programa:
Welcome to the Society of Thieves from Gandorra
Knock three times to use the society's password
Knock knock knock
The gatekeeper has heard the password. You can pass.
Y si hay más de tres knocks:
Welcome to the Society of Thieves from Gandorra
Knock three times to use the society's password
knock knock knock knock
The only thing that answers is the noise of a cricket.
Ejemplo 4
Para este último ejemplo, quiero poner a prueba tu conocimiento de expresiones regulares dándote un desafío.
Lo que debes hacer es crear un programa que lea la siguiente expresión:
John is 24, Mary is 43, Dan is 26, Carla is 32
Luego, por medio de expresiones regulares debe tomar las edades de cada persona y sumarlas para obtener el total. Como pistas dejaré:
- \d Es una secuencia especial que puede ser usada para que tengamos un match cada vez que se presente en el string un número de 0 a 9.
- int se puede usar para convertir un número dentro de una string en un entero
- findall nos permite obtener todos los matches que cumplan con la expresión regular.
Dicho esto, las condiciones están determinadas para que crees tu programa de suma de edades. Comenta los resultados obtenidos.
.
Si se te ha hecho difícil conseguir el resultado o si quieres ver una forma de solucionarlo, presta atención a lo siguiente:
import re
text = 'John is 24, Mary is 43, Dan is 26, Carla is 32'
ages = re.findall(r'[\d][\d]', text)
ages = list(map(int, ages))
print(f'The sum of everyone\'s ages is {sum(ages)}')
¿Cómo llegamos a esto?
Debido a que \d solo nos permite tomar un solo dígito del 0 al 9, tomaríamos solo un dígito de la edad. Es por esto, que hacemos uso de los sets para poder obtener más de un caracter en el número por medio de la siguiente expresión regular:
r"[\d][\d]"
Así podremos obtener matches con números como 24, 65, 79 o cualquier combinación de dos dígitos. Ahora, para poder tener todas las edades en un lugar que podamos controlar, usamos findall. Este nos permite pasar todas las edades a una lista de strings que tendremos convertir a entero.
Para hacer la conversión de una lista de string a enteros, debemos usar map, una función que en cierto modo actúa como un for sobre elementos como listas.
Esta lo que hará es aplicar una función específica a cada elemento del iterable (en este caso nuestra lista) y nos devolverá todos estos resultados dentro de un objeto tipo map. Los objetos tipo map son iterables también y pueden convertirse a otros tipos de iterables usando las funciones list(), set(), etc...
La síntaxis de map sería la siguiente:
map(function, iterable)
Así, usamos int, la cual es una función que convierte el contenido de un elemento en un entero, y aplicamos esto sobre la lista que findall creó.
Finalmente, sumamos las edades. Esto lo hacemos por medio de sum(), una función que nos permite sumar el valor de todos los elementos de una lista de enteros. Así, al ejecutar:
The sum of everyone's ages is 125
Como puedes ver, las expresiones regulares nos salvan de gran cantidad de dolores de cabeza, infinidad de ciclos y condicionales. Es por esto que son tan utilizadas en la programación moderna, ahorrándonos líneas de código.
Después de este y los dos posts previos, tendrás un entendimiento completo de las expresiones regulares y como utilizarlas a tu ventaja, creando programas eficientes que nos permiten manejar las strings a un nuevo nivel.
Estoy ansioso de ver tus próximos proyectos.
¡Gracias por tu apoyo y buena suerte!