我试图使用Pyparsing将像aaa:bbb(123)
这样的字符串拆分为令牌。Pyparsing中的贪婪表达式
我可以用正则表达式来做到这一点,但我需要通过Pyparsing来做到这一点。
随着re
的解决方案将是这样的:
>>> import re
>>> string = 'aaa:bbb(123)'
>>> regex = '(\S+):(\S+)\((\d+)\)'
>>> re.match(regex, string).groups()
('aaa', 'bbb', '123')
这是不够清晰和简单。这里的关键点是\S+
,意思是“除空格之外的所有东西”。现在
我会尝试用Pyparsing做到这一点:
>>> from pyparsing import Word, Suppress, nums, printables
>>> expr = (
... Word(printables, excludeChars=':')
... + Suppress(':')
... + Word(printables, excludeChars='(')
... + Suppress('(')
... + Word(nums)
... + Suppress(')')
...)
>>> expr.parseString(string).asList()
['aaa', 'bbb', '123']
好吧,我们已经得到了相同的结果,但是这并不好看。我们设置excludeChars
来使Pyparsing表达式停止在我们需要的位置,但这看起来不健壮。如果我们将在源字符串“排除”字符,相同的正则表达式将正常工作:
>>> string = 'a:aa:b(bb(123)'
>>> re.match(regex, string).groups()
('a:aa', 'b(bb', '123')
而Pyparsing异常会明显突破:
>>> expr.parseString(string).asList()
Traceback (most recent call last):
File "<input>", line 1, in <module>
File "/long/path/to/pyparsing.py", line 1111, in parseString
raise exc
ParseException: Expected W:(0123...) (at char 7), (line:1, col:8)
所以,问题是我们如何才能实现Pyparsing需要的逻辑?