2015-06-18 62 views
3

我有一個字符串組成的單詞列表,我試圖用pyparsing解析。非貪婪列表解析與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 

我問題是我沒有得到相同的結果LT與非正則表達式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) 

因爲一次或更多吸食所有在列表中的單詞。我迄今爲止嘗試用FollowedBy或NotAny防止這種貪婪行爲的嘗試都失敗了 - 我有什麼建議可以獲得所需的行爲?

回答

2

那麼,你的OneOrMore表達式只需要一點點收緊 - 你在FollowedBy的正確軌道上。你不是真的只想OneOrMore(單詞),你想要的是「OneOrMore(至少跟着2個單詞的單詞)」。要添加這種超前的向pyparsing,你甚至可以使用新的「*」乘法運算符來指定先行計數:

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 
+0

非常感謝你的答案,我失敗了,因爲我在OneOrMore之外添加了FollowedBy,例如: pp.OneOrMore(word)pp.FollowedBy(word + word) –