Auto-generación de expresiones regulares a partir de listas de palabras con Python
Hacer expresiones regulares (REGEX) es una mierda a veces. No nos engañemos.
Si necesitamos crear una REGEX que coincida con un conjunto de palabras, necesitamos analizarlas e incluir todas las condiciones necesarias para que coincidan.
Para los que no pilotéis mucho de programación, es muy común en aplicaciones web, filtros, o cualquier cosa que tenga que coincidir si una palabra coincide con un conjunto de palabras permitidas.
Y, spoiler, no es fácil y la gente la caga mucho.
Venga, vamos a ponernos en situación. Imagina que quieres detectar lenguaje y gente malhablada (vamos, este post, por ejemplo).
Podrías tirar unas cuantas lineas de Python como estas:
import re
bad_words_regex = re.compile(r'''([bB][aA][sS][tT][aA][rR][dD]|[fF][uU][cC][kK])''')
word = input("Introduce tu palabra")
if bad_words_regex.match(word) is not None:
print("¡Ehhhhhh, modera tu lenguaje!")
else:
print("¡Bien hecho, chaval!")
Qué hace esto? Pues básicamente, si introduces una palabra como “ass”, “bastard”, “fuck” o palabras igual de entrañables en inglés; te dirá que laves la boca con jabón. Sino, pues te dará una palmadita en la espalda.
Ahora fíjate en la REGEX. Es un coñazo. Y encima es fácil que se te vaya la olla a mitad y la líes.
En lugar de picarte tú la REGEX a mano, puedes usar un Trie. Hay un proyecto muy chulo de Python que lo hace por ti: Trieregex.
Lo que hace Trieregex es generarte la REGEX automáticamente a partir de una serie de palabras. Algo así como sacarte factor común.
El código es facilito, no te creas tampoco que ingeniería de cohetes:
import re
from trieregex import TrieRegEx as TRE
words = ['bastard', 'fuck', 'losser']
# Add word(s)
tre = TRE(*words) # word(s) can be added upon instance
# Create regex pattern from the trie
regex_pattern = tre.regex()
# Add boundary context and compile for matching
bad_words_regex = re.compile(f'\\b{regex_pattern}\\b')
word = input("Introduce tu palabra")
if bad_words_regex.match(word) is not None:
print("¡Ehhhhhh, modera tu lenguaje!")
else:
print("¡Bien hecho, chaval!")
A este código le puedes dar más vuelta y mejorarlo hasta el infinito, obviamente. Pero creo que la idea queda clara.
Referencias
- Trieregex: https://github.com/ermanh/trieregex
- Trie: https://en.wikipedia.org/wiki/Trie