Je suis en train d'écrire une fonction parse
telle que, par exemple,pyparsing, comment arrêter un Regex de consommer toute la chaîne
assert parse("file://foo:bar.txt:r+") == ("foo:bar.txt", "r+")
La chaîne se compose d'un préfixe fixe file://
, suivi d'un nom de fichier (qui peut être constitué d'un ou de plusieurs caractères), suivi d'un deux-points et d'une chaîne représentant les indicateurs d'accès.
Voici une mise en œuvre en utilisant des expressions régulières:
import re
def parse(string):
SCHEME = r"file://" # File prefix
PATH_PATTERN = r"(?P<path>.+)" # One or more of any character
FLAGS_PATTERN = r"(?P<flags>[rwab+0-9]+)" # The letters r, w, a, b, a '+' symbol, or any digit
FILE_RESOURCE_PATTERN = SCHEME + PATH_PATTERN + r":" + FLAGS_PATTERN + r"$" # The full pattern including the end of line character
tokens = re.match(FILE_RESOURCE_PATTERN, string).groupdict()
return tokens['path'], tokens['flags']
Je préférerais utiliser PyParsing, cependant, car il donne généralement des messages d'erreur plus détaillés si la chaîne ne correspond pas à l'expression (plutôt que re.match
qui retourne simplement None
), et je voudrais éventuellement rendre le flags
optionnel.
Après la réponse de Paul McGuire dans python regex in pyparsing, je fait la tentative suivante:
from pyparsing import Word, alphas, nums, StringEnd, Regex, FollowedBy, Suppress, Literal
def parse(string):
scheme = Literal("file://")
path = Regex(".+")
flags = Word(alphas + nums + "+")
expression = Suppress(scheme) + (~(Suppress(":") + flags + StringEnd()) + path("path") + Suppress(":") + flags("flags") + StringEnd())
tokens = expression.parseString(string)
return tokens['path'], tokens['flags']
Dans la deuxième partie de l'expression, je suis en train essentiellement le négatif (~suffix + path + suffix)
préanalyse, où suffix
est ":" + flags + StringEnd()
. Cependant, lorsque vous essayez d'analyser "file://foo:bar.txt:r+"
, je lance dans l'erreur suivante:
pyparsing.ParseException: Expected ":" (at char 21), (line:1, col:22)
Depuis la chaîne est de 21 caractères, j'interprète cela comme le Regex
a « consommé » toute la chaîne de sorte que le suffixe est pas plus "trouvé".
Comment puis-je corriger la méthode parse
en utilisant pyparsing
?
Dans votre solution re, le moteur re peut faire préanalyse et retours en arrière pour trouver le « : », mais pyparsing, la re dans le Regex ne connaît pas les éléments suivants Supprimer (':') l'expression. Essayez de changer 'path' en' Regex (r "[^:] +") ', qui consommera tout sauf ':' s. – PaulMcG
[Paul McGuire] (http://stackoverflow.com/users/165216/paul-mcguire), en fait le 'chemin' peut contenir des deux-points (': 's), comme dans l'exemple, où il est' foo: bar .txt'. Donc, omettre des deux-points de 'Regex' ne ferait pas. –