Python中的递归嵌套表达式

时间:2010-02-01 00:27:05

标签: python regex nested expression

我正在使用Python 2.6.4。

我在文本文件中有一系列select语句,我需要从每个select查询中提取字段名称。如果某些字段没有使用像to_char()等嵌套函数,这将很容易。

如果select语句字段可能有多个嵌套括号,如“ltrim(rtrim(to_char(base_field_name,format)))renamed_field_name”,或者只是“base_field_name”的简单情况作为字段,是否可以使用Python的re模块写一个正则表达式来提取base_field_name?如果是这样,正则表达式会是什么样子?

6 个答案:

答案 0 :(得分:11)

正则表达式不适合解析“嵌套”结构。相反,请尝试使用完整的解析工具包,例如pyparsing - 例如,可以找到专门用于解析SQL的pyparsing的示例herehere(毫无疑问)需要以示例为出发点,并编写一些自己的解析代码,但是,这绝对不是太难)。

答案 1 :(得分:2)

>>> import re
>>> string = 'ltrim(rtrim(to_char(base_field_name, format))) renamed_field_name'
>>> rx = re.compile('^(.*?\()*(.+?)(,.*?)*(,|\).*?)*$')
>>> rx.search(string).group(2)
'base_field_name'
>>> rx.search('base_field_name').group(2)
'base_field_name'

答案 2 :(得分:2)

Alex Martelli建议的表驱动解析器或手写递归下降解析器。他们写作并不难,也很有收获。

答案 3 :(得分:1)

这可能已经足够了:

import re
print re.match(r".*\(([^\)]+)\)", "ltrim(to_char(field_name, format)))").group(1)

您需要进一步处理。例如,也可以选择函数名称并根据函数签名拉取字段名称。

.*(\w+)\(([^\)]+)\)

答案 4 :(得分:1)

这是一个真正的hacky解析器,可以满足您的需求。

它通过在要解析的文本上调用'eval'来工作,将所有标识符映射到返回其第一个参数的函数(我猜测的是你想要的例子)。

class FakeFunction(object):
    def __init__(self, name):
        self.name = name
    def __call__(self, *args):
        return args[0]
    def __str__(self):
        return self.name

class FakeGlobals(dict):
    def __getitem__(self, x):
        return FakeFunction(x)

def ExtractBaseFieldName(x):
    return eval(x, FakeGlobals())

print ExtractBaseFieldName('ltrim(rtrim(to_char(base_field_name, format)))')

答案 5 :(得分:0)

你真的需要正则表达式吗?为了得到你在那里的那个,我会用

  s[s.rfind('(')+1:s.find(')')].split(',')[0]

包含原始字符串的's'。

当然,这不是一般解决方案,但是......