Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/325.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 您可以使用单个正则表达式来解析函数参数吗?_Python_Regex_Parsing - Fatal编程技术网

Python 您可以使用单个正则表达式来解析函数参数吗?

Python 您可以使用单个正则表达式来解析函数参数吗?,python,regex,parsing,Python,Regex,Parsing,问题 有一个程序文件在文件中的某个位置包含以下代码段 ... food($apples$ , $oranges$ , $pears$ , $tomato$){ ... } ... 此函数可以包含任意数量的参数,但它们必须是用逗号分隔的字符串。所有参数字符串都是小写字 我希望能够使用正则表达式解析出每个参数。例如,python中的结果列表如下所示: ["apples", "oranges", "pears", "tomato"] 尝试的解决方案 使用pythonre模块,我能够通过将问

问题

有一个程序文件在文件中的某个位置包含以下代码段

...

food($apples$ , $oranges$ , $pears$ , $tomato$){
  ...
}

...
此函数可以包含任意数量的参数,但它们必须是用逗号分隔的字符串。所有参数字符串都是小写字

我希望能够使用正则表达式解析出每个参数。例如,python中的结果列表如下所示:

["apples", "oranges", "pears", "tomato"]
尝试的解决方案

使用pythonre模块,我能够通过将问题分为两部分来实现这一点

  • 在代码中找到函数并提取参数列表

    plist = re.search(r'food\((.*)\)', programString).group(1)
    
  • 使用另一个正则表达式拆分列表

    params = re.findall(r'[a-z]+', plist)
    
  • 问题

    我是否可以用一个正则表达式而不是两个正则表达式来实现这一点

    编辑

    多亏了Tim Pietzcker的回答,我找到了一些相关的问题:


  • 像这样的正则表达式应该有用

    food\((\$(?<parm>\w+)\$\s*,?\s*)+\).*
    
    food\(\$(?\w+)\$\s*,?\s*)+\)*
    

    它将所有匹配的参数名放在'parm'组中

    Pyparsing对于这类事情非常方便,因为您不知道何时会遇到额外的空格、注释等等。与RE中的命名组一样,此示例定义了用于检索所需数据的结果名称“parameters”:

    >>> code = """\
    ... ...
    ...
    ... food($apples$ , $oranges$ , $pears$ , $tomato$){
    ...   ...
    ... }
    ... ...
    ... food($peanuts$, $popcorn$ ,$candybars$ ,$icecream$){
    ...   ...
    ... }
    ... """
    >>> from pyparsing import *
    >>> LPAR,RPAR,LBRACE,RBRACE,DOLLAR = map(Suppress,"(){}$")
    >>> param = DOLLAR + Word(alphas) + DOLLAR
    >>> funcCall = "food" + LPAR + delimitedList(param)("parameters") + RPAR + LBRACE
    >>> for fn in funcCall.searchString(code):
    ...   print fn.parameters
    ...
    ['apples', 'oranges', 'pears', 'tomato']
    ['peanuts', 'popcorn', 'candybars', 'icecream']
    
    如果我将第二个函数更改为:

    ... food($peanuts$, $popcorn$ ,/*$candybars$ ,*/$icecream$){
    
    然后添加以下行:

    >>> funcCall.ignore(cStyleComment)
    
    然后我得到:

    >>> for fn in funcCall.searchString(code):
    ...   print fn.parameters
    ...
    ['apples', 'oranges', 'pears', 'tomato']
    ['peanuts', 'popcorn', 'icecream']
    
    回答您的问题“可以在单个正则表达式中完成吗?”:可以,但不能在Python中完成

    如果您想像您的示例中那样,仅使用单个正则表达式(单独)匹配和捕获未知数量的匹配,那么您需要。目前只有.NET和Perl 6这样做

    因此,在Python中,您要么需要分两步完成(
    find
    整个
    food(…)
    函数调用,然后
    findall
    按照Dingo的建议使用第二个正则表达式进行单独匹配)

    或者使用Paul McGuire的
    pyparsing

    为什么使用正则表达式

    for line in open("file"):
        line=line.rstrip()
        if line.lstrip().startswith("food") :
            for item in line.split(")"):
                if "food" in item:
                    print item.split("(")[-1].split(",")
    
    输出

    $ ./python.py
    ['$apples$ ', ' $oranges$ ', ' $pears$ ', ' $tomato$']
    

    从我看来,这是行不通的,因为可能还有其他函数也有字符串的参数列表。我只需要“food”函数中的参数列表。这不是只返回第一个参数吗?不,它应该返回parm组中的所有参数。它只返回最后一个参数+命名组use
    (?P…)
    syntax有很多方法可以实现我想要的;然而,我很好奇是否可以用一个正则表达式来实现。谢谢你回答我的问题。
    $ ./python.py
    ['$apples$ ', ' $oranges$ ', ' $pears$ ', ' $tomato$']