Convertir les arguments de ligne de commande à l'expression régulière
Dire, par exemple, je veux savoir si le modèle "\section" qui est dans le texte "abcd\sectiondefghi". Bien sûr, je peux le faire:
import re
motif = r"\\section"
txt = r"abcd\sectiondefghi"
pattern = re.compile(motif)
print pattern.findall(txt)
Qui va me donner ce que je veux. Cependant, chaque fois que je veux trouver un nouveau modèle dans un nouveau texte, j'ai du modifier le code ce qui est douloureux. Donc, je veux écrire quelque chose de plus souple, comme ceci (test.py
):
import re
import sys
motif = sys.argv[1]
txt = sys.argv[2]
pattern = re.compile(motif)
print pattern.findall(txt)
Alors, je veux l'exécuter dans le terminal comme ceci:
python test.py \\section abcd\sectiondefghi
Toutefois, cela ne marchera pas (je déteste utiliser \\\\section
).
Donc, est-il un moyen de convertir mon entrée de l'utilisateur (soit à partir du terminal ou à partir d'un fichier) pour python chaîne brute? Ou est-il une meilleure façon de faire le modèle d'expression régulière de compilation à partir de la saisie de l'utilisateur?
Merci beaucoup.
- Notez que cette question n'est pas vraiment à propos de la conversion d'une chaîne d'une chaîne brute. Ici, le problème est tout simplement que le shell en cours d'exécution dans le terminal vous oblige à échapper aux arguments de ligne de commande. La plupart des shells tournera que
\s
danscd\sec
en un vieuxs
caractère. Peu importe ce que vous faites dans le code python, vous ne serez pas en mesure de dire qu'il y avait une barre oblique inverse devant ques
. Pour une question qui est vraiment sur la façon de transformer les caractères spéciaux dans une chaîne de caractères dans des séquences d'échappement, voir ici.
Vous devez vous connecter pour publier un commentaire.
Utilisation
re.escape()
pour s'assurer de saisie de texte est traité comme du texte littéral dans une expression régulière:Démo:
re.escape()
échappe à tous les non-alphanumériques, l'ajout d'une barre oblique inverse devant de chaque personnage:python turn string into literal for regex
. Merci!re.escape()
pour s'assurer que les métacaractères dans la plaine de texte ne sont pas interprétés comme tels.\s
en normals
caractère. Peu importe ce que vous faites dans le code python, l'entrée sera un simple vieuxs
impossible à distinguer de toute autres
.Une façon de faire cela est d'utiliser un argument de l'analyseur, comme
optparse
ouargparse
.Votre code devrait ressembler à quelque chose comme ceci:
Un exemple de moi de l'utiliser:
À l'aide de votre exemple:
Donc, juste pour être clair, c'est la chose que vous recherchez ("\section" dans votre exemple) censée être une expression régulière ou un littéral de chaîne? Dans ce dernier cas, le
re
module n'est pas vraiment le bon outil pour la tâche, étant donné une chaîne de rechercheneedle
et une chaîne ciblehaystack
, vous pouvez le faire:qui sont toutes plus efficace que la regexp version.
re.escape
est toujours utile si vous avez besoin d'insérer un littéral fragment dans un plus grand regexp au moment de l'exécution, mais si vous finissez par fairere.compile(re.escape(needle))
, il existe pour la plupart des cas, de meilleurs outils pour la tâche.EDIT: je commence à soupçonner que le vrai problème ici est que le shell de s'échapper de règles, ce qui n'a rien à voir avec Python ou de matières premières chaînes. C'est, si vous tapez:
dans un style Unix, shell, l' "\section" la partie est convertie en "\section" par le shell, avant de Python voit. La façon la plus simple pour fixer c'est-à-dire la coquille de sauter unescaping, qui vous pouvez le faire en mettant l'argument à l'intérieur des guillemets simples:
De comparer et de contraste:
(explicitement à l'aide de l'impression sur un joint chaîne ici pour éviter
repr
ajoutant encore plus de confusion...)