Я пытаюсь разбить строку, как aaa:bbb(123)
, в токены, используя Pyparsing.Жадные выражения в 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?