2013-05-01 23 views
3

我試圖用pyparsing解析其中的參數本身可能包含反斜線線的延續,如下面的例子爲-arg4值命令行風格的字符串:pyparsing命令行字符串延長部

import pyparsing as pp 

cmd = r"""shellcmd -arg1 val1 -arg2 val2 \ 
-arg3 val3 \ 
-arg4 'quoted \ 
    line-continued \ 
    string \ 
'""" 

continuation = '\\' + pp.LineEnd() 

option = pp.Word('-', pp.alphanums) 
arg1 = ~pp.Literal('-') + pp.Word(pp.printables) 
arg2 = pp.quotedString 
arg2.ignore(continuation) 
arg = arg1 | arg2 

command = pp.Word(pp.alphas) + pp.ZeroOrMore(pp.Group(option + pp.Optional(arg))) 
command.ignore(continuation) 

print command.parseString(cmd) 

結果是:

['shellcmd', ['-arg1', 'val1'], ['-arg2', 'val2'], ['-arg3', 'val3'], ['-arg4', "'quoted"]] 

當我想是這樣的:

['shellcmd', ['-arg1', 'val1'], ['-arg2', 'val2'], ['-arg3', 'val3'], ['-arg4', 'quoted line-continued string']] 

我非常感謝您的指導,指出我的錯誤和修復。

回答

4

使用cmd因爲你已經張貼在它上面,我會分析它是這樣的:

from pyparsing import * 

continuation = ('\\' + LineEnd()).suppress() 
name = Word(alphanums) 

# Parse out the multiline quoted string 
def QString(s,loc,tokens): 
    text = Word(alphanums+'-') + Optional(continuation) 
    g = Combine(ZeroOrMore(text),adjacent=False, joinString=" ") 
    return g.parseString(tokens[0]) 

arg = name + Optional(continuation) 
qarg = QuotedString("\'",multiline=True) 
qarg.setParseAction(QString) 

vals = Group(ZeroOrMore(arg | qarg)) 
option = Literal("-").suppress() + Group(name + vals) 
grammar = name + ZeroOrMore(option) 

sol = grammar.parseString(cmd) 
print sol 

,並提供:

['shellcmd', ['arg1', ['val1']], ['arg2', ['val2']], ['arg3', ['val3']], ['arg4', ['quoted line-continued string']]] 

真正的關鍵在這裏使用QuotedString選項multiline=True從而節省了很多頭痛。這個解決方案比您提出的解決方案更靈活一些,能夠處理多個參數,即-arg a b c甚至-arg a b 'long-string-with-dashes' c d e

+0

非常感謝。你解決了我的問題。 – 2013-05-02 20:12:04

+0

@KeithWald我很高興,幫助和歡迎堆棧溢出!如果您的解決方案已解決,請點擊複選標記以「接受」答案。 – Hooked 2013-05-02 20:25:04