Rendre les scripts Python plus intelligents avec les regex : 5 exemples pratiques
Si vous travaillez avec des chaînes dans vos scripts Python et que vous écrivez une logique obscure pour les traiter, vous devez alors vous pencher sur les expressions régulières en Python. Il vous permet de décrire des modèles au lieu d'écrire une logique procédurale. Examinons quelques exemples concrets où Python re Le module rend les scripts plus intelligents.
Sommaire
Valider les entrées utilisateur sournoises
Lors de la validation d'une entrée utilisateur sans regex, vous avez probablement écrit du code qui ne vous semblait pas correct. Supposons que vous souhaitiez valider un nom d'utilisateur avec ces règles :
-
Uniquement les lettres, les chiffres et les traits de soulignement
-
Doit commencer par une lettre
-
Longueur entre 3 et 16 caractères
Il s’agit d’une exigence courante. Voyons ce que vous devez faire sans utiliser Python re module:
def is_valid_username(username):
if len(username) < 3 or len(username) > 16:
return False
if not username(0).isalpha():
return False
for char in username:
if not (char.isalnum() or char == "_"):
return False
return True
Cela fonctionne, mais c'est verbeux, facile à gâcher, et chaque nouvelle règle implique l'ajout de plus de logique. C'est exactement là que le re le module brille. Vous décrivez les règles de manière déclarative en utilisant re.compile() et utilisez ce modèle partout :
import re
USERNAME_PATTERN = re.compile(r"^(a-zA-Z)(a-zA-Z0-9_){2,15}$")
def is_valid_username(username):
return bool(USERNAME_PATTERN.fullmatch(username))
Comprenons ce qui se passe.
-
^: Ceci indique le début de la chaîne -
(a-zA-Z): Doit commencer par une lettre -
(a-zA-Z0-9_){2,15}: Les caractères autorisés et la longueur restante -
$: Ceci indique la fin de la chaîne
Une fois que vous commencez à valider les entrées avec reil devient difficile de revenir en arrière. Vous exprimez les règles directement et Python fait le gros du travail.
6 raisons pour lesquelles Python interactif change la donne pour moi
Pas de programme ? Aucun problème!
À un moment donné, chaque script Python se heurte à du texte désordonné. Fichiers journaux, captures de paquets, e-mails, HTML gratté, entre autres. Le défi consiste à extraire cette structure sans écrire de code d’analyse fragile ligne par ligne.
Imaginez que vous traitez un fichier journal d'application et que vous souhaitez extraire les horodatages et les messages d'erreur. Une ligne de journal typique pourrait ressembler à ceci :
(2025-01-02 14:33:21) ERROR: Connection timed out after 30 seconds
Vous pouvez essayer comme ceci :
def parse_log_line(line):
if not line.startswith("("):
return None
parts = line.split(")")
timestamp = parts(0)(1:)
if "ERROR:" not in parts(1):
return None
message = parts(1).split("ERROR:")(1).strip()
return timestamp, message
Cela fonctionne pour le format exact avec lequel vous avez testé. Mais c'est fragile. Des espaces supplémentaires, des crochets manquants ou une formulation légèrement différente peuvent briser la logique. De plus, l’intention du code est enfouie sous la gymnastique aux cordes. Avec le re module, vous pouvez décrire la structure de la ligne au lieu de la découper manuellement.
import re
LOG_PATTERN = re.compile(
r"((?P(d-: )+))s+ERROR:s+(?P.+)"
)
def parse_log_line(line):
match = LOG_PATTERN.search(line)
if not match:
return None
return match.group("timestamp"), match.group("message")
Ici, nous disons à Python exactement ce que nous recherchons : un horodatage entre parenthèses, suivi du mot « ERREUR », suivi du reste du message.
Nettoyer et normaliser le texte sur une seule ligne
Le nettoyage de texte est l'une de ces tâches qui semblent simples jusqu'à ce que vous la fassiez réellement. Vous devez souvent faire face à des espaces supplémentaires, des séparateurs incohérents, une ponctuation aléatoire ou des bizarreries de formatage qui rendent la logique en aval ennuyeuse.
Supposons que vous traitiez du texte soumis par l'utilisateur et que vous souhaitiez le normaliser avant de le stocker ou de le comparer. Vos règles sont :
-
Supprimer les espaces de début et de fin
-
Remplacez plusieurs espaces, tabulations ou nouvelles lignes par un seul espace
-
Supprimer les caractères non alphanumériques (sauf les espaces)
-
Convertir tout en minuscule
Sans utiliser reune approche typique pourrait ressembler à ceci :
def clean_text(text):
text = text.strip()
text = text.replace("n", " ").replace("t", " ")
while " " in text:
text = text.replace(" ", " ")
cleaned = ()
for char in text:
if char.isalnum() or char == " ":
cleaned.append(char)
return "".join(cleaned).lower()
Ce n'est pas terrible, mais c'est bruyant. L'intention est dispersée dans des boucles et des opérations répétées. Et si vous souhaitez modifier les règles, vous modifiez à nouveau plusieurs lignes.
Avec Python re.sub()vous pouvez décrire motifs de désordre au lieu de les traiter un cas à la fois.
import re
def clean_text(text):
text = re.sub(r"s+", " ", text) # normalize whitespace
text = re.sub(r"(^a-zA-Z0-9 )", "", text) # remove punctuation
return text.strip().lower()
C'est la même logique, exprimée bien plus clairement.
7 façons utiles de manipuler un fichier texte avec Python
Arrêtez de vous disputer avec vos fichiers et utilisez Python pour effectuer toutes les tâches banales.
Recherche et remplacement intelligents
Chaque programmeur Python sait str.replace(). C'est simple, rapide et parfaitement bien, jusqu'à ce que vous ayez besoin de contexte. Le moment où votre remplacement dépend de l'endroit où quelque chose apparaît, de ce qui l'entoure ou d'une partie de ce que vous avez correspondant, str.replace() s'essouffle.
Imaginez que vous travaillez avec des journaux ou des données exportées contenant des informations sensibles et que vous souhaitez masquer les adresses e-mail avant de stocker ou de partager le fichier.
User john.doe@example.com logged in from 10.0.0.5
Tu veux ça :
User ***@example.com logged in from 10.0.0.5
En utilisant les méthodes de base des chaînes, cela devient vite gênant :
def mask_email(text):
words = text.split()
masked = ()
for word in words:
if "@" in word:
username, domain = word.split("@", 1)
masked.append("***@" + domain)
else:
masked.append(word)
return " ".join(masked)
Cela suppose que les e-mails sont séparés par des espaces, ne gèrent pas bien la ponctuation et mélangent l'analyse avec une logique de remplacement. Avec re.sub()vous pouvez faire correspondre directement les adresses e-mail et remplacer uniquement la partie qui vous intéresse.
import re
EMAIL_PATTERN = re.compile(r"((w.-)+)@((w.-)+.w+)")
def mask_emails(text):
return EMAIL_PATTERN.sub(r"***@2", text)
Ici, celui de Python re Le module fait le gros du travail. Le modèle trouve des chaînes de type courrier électronique n'importe où dans le texte, les groupes de capture isolent le nom d'utilisateur et le domaine, et le remplacement réutilise une partie de la correspondance via 2. Il s’agit de trouver et de remplacer avec conscience.
Analyser des données semi-structurées
Même dans une situation de niche où certaines données ne sont pas clairement structurées et sous une forme totalement libre, Python re Le module sauve tranquillement la situation. Supposons que vous receviez des chaînes comme celle-ci :
name=John age=32 role=admin active=true
Votre objectif est d’en faire un dictionnaire. Le format est cohérent, mais il n'y a aucune garantie quant à l'espacement, à l'ordre ou aux touches qui apparaissent. Vous savez simplement qu'il s'agit d'une séquence de paires clé-valeur. Dans un premier temps, vous pourriez chercher split():
def parse_kv_string(text):
result = {}
parts = text.split()
for part in parts:
if "=" not in part:
continue
key, value = part.split("=", 1)
result(key) = value
return result
Cela fonctionne jusqu'à ce que les valeurs deviennent plus complexes, que l'espacement change ou que vous souhaitiez une validation. Encore une fois, la logique de recherche des données et celle de leur traitement sont étroitement liées.
Avec Python re.findall()vous pouvez décrire la structure directement et laisser le moteur effectuer l'analyse.
import re
KV_PATTERN = re.compile(r"(w+)=((^s)+)")
def parse_kv_string(text):
return dict(KV_PATTERN.findall(text))
Ce modèle unique exprime le format complet : une clé semblable à un mot, suivie du signe égal (=), suivi d'une valeur autre qu'un espace. Les Pythons re Le module extrait toutes les paires en un seul passage.
8 utilisations pratiques du module Python os
Construire le pont entre Python et votre système d'exploitation.
Si vous êtes un programmeur Python qui évite les expressions régulières, commencez petit. Utiliser re.fullmatch() pour validation. Essayer re.sub() la prochaine fois que vous nettoierez du texte. Une fois les modèles cliqués, vous vous retrouverez à écrire des scripts plus courts qui en font plus.
