pyparsing:将方法调用链拆分为顶级部分

时间:2019-04-30 09:07:38

标签: pyparsing

如果我在Python中有一连串的方法调用,该如何使用pyparsing提取顶级调用?

Tldr;该函数应该这样操作:

_parse_commands("df.hi()[['fi']](__call__).NI(ni='NI!')")
['df', '.hi()', "[['fi']]", '(__call__)', ".NI(ni='NI!')"]

我什至无法正确解析方法调用:

from pyparsing import Word, alphas, nums, Literal, alphanums, printables, Optional, locatedExpr, originalTextFor, SkipTo

identifier = Word(alphas + '_', alphanums + '_').setName("identifier")
lparen = Literal("(")
rparen = Literal(")")
function_call = identifier + lparen + Optional(printables) + rparen

function_call.parseString("hi()")
# (['hi', '(', ')'], {})
# but
function_call.parseString("hi(ho)")
# ...
# ParseException: Expected ")" (at char 3), (line:1, col:4)

一个问题是,我似乎找不到任何方法告诉pyparsing“在定界符之间获取任何内容”-这就是我在上面的可打印对象中尝试的方法。我也尝试过originalTextFor解决相同的问题。

此外,如果答案可以使用locatedExpr给出函数调用的位置,那将会很不错。

1 个答案:

答案 0 :(得分:1)

实际上,解析这些表达式并非易事,因为您几乎需要定义任何种类的Python表达式。

但是,由于您只想分割嵌套括号,因此可以使用pyparsing内置nestedExpr()(默认为嵌套()的表达式),并使用scanString扫描输入字符串以查找匹配项。每次匹配都返回令牌,开始和结束位置的元组。通过跟踪最后看到的末端,然后在存在匹配项时,可以通过从last_end到当前起始位置的切片来重建中间文本:

src = "df.hi()[['fi']](__call__).NI(ni='NI!')"
import pyparsing as pp

last_e = 0
for t, s, e in pp.nestedExpr().scanString(src):
    print(src[last_e:s])
    print(s)
    print(t.asList())
    print(src[s:e])
    print(e)
    print()
    last_e = e

# get whatever is left after the last parens
print(src[last_e:])

打印:

df.hi
5
[[]]
()
7

[['fi']]
15
[['__call__']]
(__call__)
25

.NI
28
[['ni=', "'NI!'"]]
(ni='NI!')
38

从这里您应该能够获取想要的位。