非贪婪列表解析与pyparsing

时间:2015-06-18 14:21:28

标签: python pyparsing non-greedy

我有一个字符串,其中包含我试图用pyparsing解析的单词列表。

列表始终至少有三个项目。从这里我想要pyparsing生成三个组,第一组包含最后两个项目的所有单词,最后两个组应该是最后两个项目。例如:

"one two three four"

应解析为类似的东西:

["one two"], "three", "four"

我可以使用正则表达式执行此操作:

import pyparsing as pp
data = "one two three four"
grammar = pp.Regex(r"(?P<first>(\w+\W?)+)\s(?P<penultimate>\w+) (?P<ultimate>\w+)")
print(grammar.parseString(data).dump())

给出:

['one two three four']
- first: one two
- penultimate: three
- ultimate: four

我的问题是我没有得到与非正则表达ParserElement相同的结果,因为pyparsing贪婪的性质,例如以下:

import pyparsing as pp
data = "one two three four"
word = pp.Word(pp.alphas)
grammar = pp.Group(pp.OneOrMore(word))("first") + word("penultimate") + word("ultimate")
grammar.parseString(data)

以跟踪失败:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.7/site-packages/pyparsing.py", line 1125, in parseString
    raise exc
pyparsing.ParseException: Expected W:(abcd...) (at char 18), (line:1, col:19)

因为OneOrMore会啜饮列表中的所有单词。到目前为止,我尝试使用FollowedBy或NotAny防止这种贪婪的行为失败了 - 任何关于如何获得所需行为的建议?

1 个答案:

答案 0 :(得分:3)

嗯,你的OneOrMore表达只需要稍微收紧一点 - 你跟随FollowedBy走在正确的轨道上。你真的不想要OneOrMore(单词),你想要&#34; OneOrMore(跟着至少2个单词的单词)&#34;。要为pyparsing添加这种前瞻,你甚至可以使用新的&#39; *&#39;乘法运算符指定先行计数:

grammar = pp.Group(pp.OneOrMore(word + pp.FollowedBy(word*2)))("first") + word("penultimate") + word("ultimate")

现在把它倾倒出来可以得到所需的:

[['one', 'two'], 'three', 'four']
- first: ['one', 'two']
- penultimate: three
- ultimate: four
相关问题