在 PyParsing 中,如何阻止正则表达式使用整个字符串



我正在尝试编写一个函数parse例如,

assert parse("file://foo:bar.txt:r+") == ("foo:bar.txt", "r+")

该字符串由一个固定前缀file://组成,后跟文件名(可以由一个或多个任何字符组成),后跟冒号和表示访问标志的字符串。

下面是一个使用正则表达式的实现:

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']

但是,我更喜欢使用 PyParsing,因为如果字符串与表达式不匹配,它通常会给出更详细的错误消息(而不是re.match它只返回None),我最终想使flags可选。

按照 Paul McGuire 在 python 正则表达式中的 pyparsing 中的回答,我做了以下尝试:

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']

在表达式的第二部分,我基本上是在尝试负前瞻(~suffix + path + suffix),其中suffix":" + flags + StringEnd()。但是,当尝试解析"file://foo:bar.txt:r+"时,我遇到了以下错误:

pyparsing.ParseException: Expected ":" (at char 21), (line:1, col:22)

由于字符串的长度为 21 个字符,因此我将其解释为Regex已经"消耗"了整个字符串,因此不再"找到"后缀。

如何使用pyparsing修复parse方法?

试试这个:

s="file://foo:bar.txt:r+"
path,flag=re.sub(r'.*//(.*):(.*$)',r'1,2',s)

最新更新