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