pyparsing:尾随空格不匹配但仍包含在 endloc 计算中
pyparsing: Trailing whitespace is not matched but still included for endloc calculation
我正在使用 Python 3.9.5 和 pyparsing==3.0.6
我有一个场景,我需要匹配一个词(alphanum)和可选的另一个词。但是,pp.Optional() 与尾随空格相结合会导致不正确的 endloc 索引。
import pyparsing as pp
def first_match(expression, text):
for m, s, e in expression.scanString(text, maxMatches=1):
return {'match': m, 'start': s, 'end': e}
return None
expr = pp.Group(
pp.Word(pp.alphanums) +
pp.Optional(
pp.Word(pp.alphanums)
)
)
在下面的测试中,一切都如我所料。整个字符串从 0 到 3 匹配。
print(first_match(expr, "one"))
# {'match': ParseResults([ParseResults(['one'], {})], {}), 'start': 0, 'end': 3}
如果我添加尾随空格,即使它们(正确)不匹配,它们也会包含在 endloc 索引计算中。所以匹配的范围是0到8:
print(first_match(expr, "one "))
# {'match': ParseResults([ParseResults(['one'], {})], {}), 'start': 0, 'end': 8}
scanString 返回的 endloc 索引不应该总是最后一个匹配字符的索引吗?
这是预期的行为,而不是 pyparsing 2.4.7 的回归。
将 Optional(expr)
视为“表达式或空”。 pyparsing 将在中间的空格上前进,然后,如果没有找到表达式,则认为解析是一个成功的匹配(因为它正在寻找的 expr 不是必需的)。
要获得您正在寻找的行为,您可以使用以下格式:
expr = pp.Group(
pp.Word(pp.alphanums) + pp.Word(pp.alphanums)
| pp.Word(pp.alphanums)
)
如果存在第二个字母词,它将同时解析它们,如果不存在,则只解析第一个。
使用和不使用第二个值进行测试:
print(first_match(expr, "one"))
print(first_match(expr, "one "))
print(first_match(expr, "one two"))
print(first_match(expr, "one two "))
给出:
{'match': ParseResults([ParseResults(['one'], {})], {}), 'start': 0, 'end': 3}
{'match': ParseResults([ParseResults(['one'], {})], {}), 'start': 0, 'end': 3}
{'match': ParseResults([ParseResults(['one', 'two'], {})], {}), 'start': 0, 'end': 11}
{'match': ParseResults([ParseResults(['one', 'two'], {})], {}), 'start': 0, 'end': 11}
我正在使用 Python 3.9.5 和 pyparsing==3.0.6
我有一个场景,我需要匹配一个词(alphanum)和可选的另一个词。但是,pp.Optional() 与尾随空格相结合会导致不正确的 endloc 索引。
import pyparsing as pp
def first_match(expression, text):
for m, s, e in expression.scanString(text, maxMatches=1):
return {'match': m, 'start': s, 'end': e}
return None
expr = pp.Group(
pp.Word(pp.alphanums) +
pp.Optional(
pp.Word(pp.alphanums)
)
)
在下面的测试中,一切都如我所料。整个字符串从 0 到 3 匹配。
print(first_match(expr, "one"))
# {'match': ParseResults([ParseResults(['one'], {})], {}), 'start': 0, 'end': 3}
如果我添加尾随空格,即使它们(正确)不匹配,它们也会包含在 endloc 索引计算中。所以匹配的范围是0到8:
print(first_match(expr, "one "))
# {'match': ParseResults([ParseResults(['one'], {})], {}), 'start': 0, 'end': 8}
scanString 返回的 endloc 索引不应该总是最后一个匹配字符的索引吗?
这是预期的行为,而不是 pyparsing 2.4.7 的回归。
将 Optional(expr)
视为“表达式或空”。 pyparsing 将在中间的空格上前进,然后,如果没有找到表达式,则认为解析是一个成功的匹配(因为它正在寻找的 expr 不是必需的)。
要获得您正在寻找的行为,您可以使用以下格式:
expr = pp.Group(
pp.Word(pp.alphanums) + pp.Word(pp.alphanums)
| pp.Word(pp.alphanums)
)
如果存在第二个字母词,它将同时解析它们,如果不存在,则只解析第一个。
使用和不使用第二个值进行测试:
print(first_match(expr, "one"))
print(first_match(expr, "one "))
print(first_match(expr, "one two"))
print(first_match(expr, "one two "))
给出:
{'match': ParseResults([ParseResults(['one'], {})], {}), 'start': 0, 'end': 3}
{'match': ParseResults([ParseResults(['one'], {})], {}), 'start': 0, 'end': 3}
{'match': ParseResults([ParseResults(['one', 'two'], {})], {}), 'start': 0, 'end': 11}
{'match': ParseResults([ParseResults(['one', 'two'], {})], {}), 'start': 0, 'end': 11}