拆分字符串,看起来像对参数的Python函数调用

拆分字符串,看起来像对参数的Python函数调用,python,Python,我试图创建一个函数,该函数接受类似于python中函数调用的字符串,并将参数返回给函数 例如: 将导致: ["1", "bar(x+17, 1)", "arr = 's,y'"] 使用正则表达式的问题是,我不知道是否可以不在括号或引号内的逗号处拆分。 谢谢 编辑:这不能正确回答伪命题,因为它不处理括号或引号中的逗号 正如@Kevin所说,正则表达式无法解决这一问题,因为它们无法处理嵌套的括号。您可以通过类似的方法来跟踪自己的状态 def parse_arguments(s): open

我试图创建一个函数,该函数接受类似于python中函数调用的字符串,并将参数返回给函数 例如:

将导致:

["1", "bar(x+17, 1)", "arr = 's,y'"]
使用正则表达式的问题是,我不知道是否可以不在括号或引号内的逗号处拆分。 谢谢

编辑:这不能正确回答伪命题,因为它不处理括号或引号中的逗号


正如@Kevin所说,正则表达式无法解决这一问题,因为它们无法处理嵌套的括号。

您可以通过类似的方法来跟踪自己的状态

def parse_arguments(s):
    openers = "{[\"'("
    closers = "}]\"')"
    state = []
    current = ""
    for c in s:
        if c == "," and not state:
           yield current
           current = ""
        else:
           current += c
           if c in openers:
              state.append(c)
           elif c in closers:
              assert state, "ERROR No Opener for %s"%c
              assert state[-1] == openers[closers.index(c)],"ERROR Mismatched %s %s"%(state[-1],c)
              state.pop(-1)
    assert not state, "ERROR Unexpected End, expected %s"%state[-1]
    yield current

print list(parse_arguments("1, bar(x+17, 1), arr = 's,y'"))

你可以很简单地用以下方法来跟踪你自己的状态

def parse_arguments(s):
    openers = "{[\"'("
    closers = "}]\"')"
    state = []
    current = ""
    for c in s:
        if c == "," and not state:
           yield current
           current = ""
        else:
           current += c
           if c in openers:
              state.append(c)
           elif c in closers:
              assert state, "ERROR No Opener for %s"%c
              assert state[-1] == openers[closers.index(c)],"ERROR Mismatched %s %s"%(state[-1],c)
              state.pop(-1)
    assert not state, "ERROR Unexpected End, expected %s"%state[-1]
    yield current

print list(parse_arguments("1, bar(x+17, 1), arr = 's,y'"))

最好使用ast抽象语法树标准库模块,尽管这可能有些过分:

>>> import ast
>>> parsed = ast.parse("fun(1, bar(x+17, 1), arr='s, y')")
>>> ast.dump(p.body[0].value)
"Call(func=Name(id='fun', ctx=Load()), args=[Num(n=1), 
Call(func=Name(id='bar', ctx=Load()), args=[BinOp(left=Name(id='x', 
ctx=Load()), op=Add(), right=Num(n=17)), Num(n=1)], keywords=[], 
starargs=None, kwargs=None)], keywords=[keyword(arg='arr', 
value=Str(s='s, y'))], starargs=None, kwargs=None)"

不幸的是,没有标准的库方法将它们返回到标准字符串,如1,barx+17,1和arr='s,y'。但是可能可以做到这一点。

最好使用ast抽象语法树标准库模块,尽管这可能有些过分:

>>> import ast
>>> parsed = ast.parse("fun(1, bar(x+17, 1), arr='s, y')")
>>> ast.dump(p.body[0].value)
"Call(func=Name(id='fun', ctx=Load()), args=[Num(n=1), 
Call(func=Name(id='bar', ctx=Load()), args=[BinOp(left=Name(id='x', 
ctx=Load()), op=Add(), right=Num(n=17)), Num(n=1)], keywords=[], 
starargs=None, kwargs=None)], keywords=[keyword(arg='arr', 
value=Str(s='s, y'))], starargs=None, kwargs=None)"

不幸的是,没有标准的库方法将它们返回到标准字符串,如1,barx+17,1和arr='s,y'。但可能可以做到这一点。

尝试一下这个复杂的拆分函数

>>> import re
>>> s = "fun(1, bar(x+17, 1), arr = 's,y')"
>>> [i.strip() for i in re.split(r'''^\w+\(|\)$|((?:\([^()]*\)|'[^']*'|"[^"]*"|[^'"(),])*)''', s) if i and i !=',']
['1', 'bar(x+17, 1)', "arr = 's,y'"]

尝试一下这个复杂的分割函数

>>> import re
>>> s = "fun(1, bar(x+17, 1), arr = 's,y')"
>>> [i.strip() for i in re.split(r'''^\w+\(|\)$|((?:\([^()]*\)|'[^']*'|"[^"]*"|[^'"(),])*)''', s) if i and i !=',']
['1', 'bar(x+17, 1)', "arr = 's,y'"]
你可以尝试使用re

输出:['1','barx+17,1',arr='s,y']

你可以尝试使用re

输出:['1','barx+17,1',arr='s,y']

基于是否有更好的字符串处理?唯一的变化是新的if-arm,允许在字符串中使用任何字符,包括转义引号

def parse_argumentss: 开场白={[\' 闭合器=}]\' 状态=[] 电流= 对于s中的c: 如果c==,而不是状态: 屈服电流 电流= 其他: 电流+=c 如果\'中的状态和状态[-1]: 如果c==状态[-1]和当前[-1]!=\\: state.pop-1 其他: 如果开孔器中有c: 国家附录C 闭合器中的elif c: 断言状态,错误%s%c没有打开程序 明确肯定 状态[-1]==开启器[关闭器.indexc] ,错误不匹配%s%s%状态[-1],c state.pop-1 断言非状态,错误意外结束,应为%s%state[-1] 屈服电流 基于更好的字符串处理?唯一的变化是新的if-arm,允许在字符串中使用任何字符,包括转义引号

def parse_argumentss: 开场白={[\' 闭合器=}]\' 状态=[] 电流= 对于s中的c: 如果c==,而不是状态: 屈服电流 电流= 其他: 电流+=c 如果\'中的状态和状态[-1]: 如果c==状态[-1]和当前[-1]!=\\: state.pop-1 其他: 如果开孔器中有c: 国家附录C 闭合器中的elif c: 断言状态,错误%s%c没有打开程序 明确肯定 状态[-1]==开启器[关闭器.indexc] ,错误不匹配%s%s%状态[-1],c state.pop-1 断言非状态,错误意外结束,应为%s%state[-1] 屈服电流
可能重复的可能重复的你应该使用正则表达式来解析括号之间的内容,然后拆分该字符串以找到你的参数。所有这些都不能正确处理括号或引号中的逗号。就像在示例中一样,正则表达式不能解析嵌套的括号。也许你可以用更高级的功能来做,但在某一点上,它会变得足够复杂,你也可以只编写一个解析器。可能重复的可能重复你应该使用正则表达式来解析括号之间的内容,然后拆分该字符串以找到您的参数所有这些都不能正确处理括号或引号中的逗号。就像在示例中一样,正则表达式不能解析嵌套的括号。也许你可以用更高级的特性来做,但在某一点上,它将足够复杂,你也可以只编写一个解析器。。。但我很确定,对于任何正则表达式,都存在一些反例,可以打破它。。用嵌套的括号+1,我不能马上想出一个好的反例,即使我可以。。。但在它不起作用的时候调试它可能有点痛苦,我认为在pipi import regex中有一个实际的regex模块,它支持堆栈内存和其他高级regex功能,所以你可以使用这个模块来找到一个完美的regex解决方案。。。但我很确定,对于任何正则表达式,都存在一些反例,它们会破坏我的理解
T用嵌套的括号+1,我不能马上想出一个好的反例,即使我可以。。。但是在它不起作用的时候调试它可能会有点痛苦,我认为在pipi导入正则表达式中有一个实际的正则表达式模块,它支持堆栈内存和其他高级正则表达式功能,因此您可以使用该模块提出一个完美的正则表达式解决方案。所有正则表达式的答案都在嵌套括号中失败。尝试x=funbar1,foo1由于所有正则表达式的答案都在嵌套括号中失败。试试x=funbar1,foo1Doesn似乎对parse_argumentshello不起作用,我想是因为它既是关闭的又是打开的?我想它也会尝试匹配字符串中的开始符/结束符,这是不应该的。我尽力做了一个增强:似乎对parse_argumentshello不起作用,我想是因为结束符和开始符都起作用了吗?我认为它还将尝试在字符串中匹配开/关,这是不应该的。我尽了最大努力进行了增强: