如果我在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“在分隔符之间取出任何东西” - 这就是我正在尝试使用上面的printables。我也尝试过originalTextFor来解决同样的问题。
此外,如果答案可以使用locateExpr来给出函数调用的位置,那就会膨胀。
实际上解析这些表达式并不是一件容易的事,因为你需要几乎定义任何类型的Python表达式。
但是既然你想在嵌套括号上拆分,那么你可以使用pyparsing内置nestedExpr()
(默认为嵌套()的表达式),并使用scanString扫描输入字符串中的匹配项。每个匹配返回一个标记,开始和结束位置的元组。通过跟踪最后看到的结束,然后当匹配时,您可以通过从last_end切换到当前start来重建介入文本:
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
从这里你应该能够得到你想要的位。