是否可以对字符串中的嵌套调用使用pyparsing?

时间:2014-11-26 21:21:38

标签: python pyparsing

我正在为配置格式开发一个解析器,它也使用函数,我试图确定是否可以使用pyparsing来执行此任务。

我的输入是

%upper(%basename(filename)fandsomemore)f%lower(test)f _ %lower(test2)f

,有限的结果应该是

FILENAMEANDSOMEMOREtest _ test2

为了做到这一点,我首先要获取函数名称和参数。我当前的代码仅适用于upper函数和嵌套的basename,并且仅适用于" andomeome"部分缺失。代码如下:

from pyparsing import *

identifier = Word(alphas)
integer  = Word(nums)
functor = identifier
expression = Forward()

lparen = Literal("%").suppress() + functor + Literal("(").suppress()
rparen = Literal(")f").suppress()

argnrec = identifier | integer
arg = Group(expression) | argnrec
args = arg + ZeroOrMore("," + argnrec)
expression << Group(lparen + args + rparen)

print expression.parseString("%upper(%basename(filename)f)f%lower(test)f%lower(test2)f")
print expression.parseString("%upper(%basename(filename)fandsomemore)f%lower(test)f _ %lower(test2)f")

这对于第一次打印和输出非常有用,正如预期的那样

[['upper', [['basename', 'filename']]]]

对于第二次打印,我有一个错误:

pyparsing.ParseException: Expected ")f" (at char 27), (line:1, col:28)

有没有办法让这个与pyparsing一起工作?如果没有,任何替代方法将不胜感激。另外,请记住,这必须处理更复杂的参数,例如Windows路径(当前代码仅适用于alpha和数字)

稍后更新: 这样做的目的是能够将函数插入字符串中的任何位置。另一种可能的用法是:

 %upper(this)f is a %lower(TEST)f and m%upper(%lower(ORE)f)f

这将导致结束

THIS is a test and mORE

1 个答案:

答案 0 :(得分:0)

只是在这里玩,我不完全确定你想要什么,但也许这会有所帮助?

from pyparsing import *

identifier = Word(alphas+nums+'_')
integer  = Word(nums)
functor = identifier
expression = Forward()

lparen = Literal("%").suppress() + functor + Literal("(").suppress()
rparen = Literal(")f").suppress()

term = (lparen + expression + rparen) | identifier
#args = term + ZeroOrMore("," + argnrec)
expression << OneOrMore(term)

print(expression.parseString("%upper(%basename(filename)f)f%lower(test)f%lower(test2)f"))
print(expression.parseString("%upper(%basename(filename)fandsomemore)f%lower(test)f _ %lower(test2)f"))

C:\temp>python test.py
['upper', 'basename', 'filename', 'lower', 'test', 'lower', 'test2']
['upper', 'basename', 'filename', 'andsomemore', 'lower', 'test', '_', 'lower', 'test2']