pyparsing:将方法调用链拆分为顶级部分
pyparsing: split chain of method calls into to top-level parts
如果我在 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 到 "fetch me anything between the delimiters" - 这就是我在上面的打印文件中尝试的。我也试过 originalTextFor 来解决同样的问题。
此外,如果答案可以使用 locatedExpr 来给出函数调用的位置,那就更好了。
实际上解析这些表达式并不简单,因为您几乎需要定义任何类型的 Python 表达式。
但是既然你只想在嵌套的括号上拆分,那么你可以使用 pyparsing 内置函数 nestedExpr()
(默认为嵌套 () 的表达式),并使用 scanString 扫描输入字符串对于比赛。每个匹配 returns 个标记、开始和结束位置的元组。通过跟踪最后看到的结束,然后当有匹配项时,您可以通过从 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
从这里你应该可以得到你想要的位。
如果我在 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 到 "fetch me anything between the delimiters" - 这就是我在上面的打印文件中尝试的。我也试过 originalTextFor 来解决同样的问题。
此外,如果答案可以使用 locatedExpr 来给出函数调用的位置,那就更好了。
实际上解析这些表达式并不简单,因为您几乎需要定义任何类型的 Python 表达式。
但是既然你只想在嵌套的括号上拆分,那么你可以使用 pyparsing 内置函数 nestedExpr()
(默认为嵌套 () 的表达式),并使用 scanString 扫描输入字符串对于比赛。每个匹配 returns 个标记、开始和结束位置的元组。通过跟踪最后看到的结束,然后当有匹配项时,您可以通过从 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
从这里你应该可以得到你想要的位。