Python中的递归嵌套表达式

Python中的递归嵌套表达式,python,regex,nested,expression,Python,Regex,Nested,Expression,我正在使用Python 2.6.4 我在一个文本文件中有一系列select语句,我需要从每个select查询中提取字段名。如果某些字段不使用嵌套函数(如to_char等),这将很容易实现 给定select语句字段可能有几个嵌套的括号,如ltrimrtrimto_charbase_field_name、格式重命名的_field_name,或者仅将base_field_name作为字段的简单情况,是否可以使用Python的re模块编写正则表达式来提取base_field_name?如果是这样,正则表

我正在使用Python 2.6.4

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


给定select语句字段可能有几个嵌套的括号,如ltrimrtrimto_charbase_field_name、格式重命名的_field_name,或者仅将base_field_name作为字段的简单情况,是否可以使用Python的re模块编写正则表达式来提取base_field_name?如果是这样,正则表达式会是什么样子

正则表达式不适合解析嵌套结构。相反,您可以尝试使用一个完整的解析工具包,例如-专门使用pyparsing解析SQL的示例,例如,您无疑需要将这些示例作为起点,编写一些自己的解析代码,但是,这肯定不是太难。

或者是Alex Martelli建议的表驱动解析器,或者是手写的递归下降解析器。它们不难写,也不值得写。

这可能足够好了:

>>> 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'
import re
print re.match(r".*\(([^\)]+)\)", "ltrim(to_char(field_name, format)))").group(1)
您需要做进一步的处理。例如,也可以提取函数名,并根据函数签名提取字段名

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

你真的需要正则表达式吗?要得到你在上面的那个我会用

  s[s.rfind('(')+1:s.find(')')].split(',')[0]
使用包含原始字符串的“s”


当然,这不是一个通用的解决方案,但是…

这里有一个真正的黑客解析器,它可以满足您的需要

它的工作原理是对要解析的文本调用'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)))')

+1为了记住括号中的表达式,所有Chomsky Type-2语言都需要不止一个regexp才能正确解析:你错了,它们适合于这样的情况,只是python还不支持它。。。匹配嵌套成对括号的纯PCRE正则表达式看起来像^?P\?P?>[^]+| P>pn*\$,它将匹配1+2*3,匹配的组v将包含1+2*3。这为我打印“字段名称,格式”,而不是“字段名称”,而且对于简单的字符串“field_name”也不起作用。您如何知道每个函数都将接受相同的参数?PS:正如Alex Martelli所说的,您应该在这里使用真正的解析器。无论如何,如果你只想要一个快速的正则表达式,你可以使用它。但是你真的应该使用一个解析器,因为这个正则表达式看起来很难看:我不想要看起来漂亮的东西,因为它是一个一次性的工具,可以让我得到我想要的数据,这样我就可以用它做其他事情了但是谢谢,我的正则表达式已经生锈了,我想有人可能知道得更清楚。编译的正则表达式应该比这个快得多。嗯,我想我们并不着急,但还是为了提高效率。你可能会发现直接使用字符串更快。这在很大程度上取决于正则表达式以及在不使用正则表达式的情况下编写等效代码的复杂性。实际上,你试过比较它们吗?哦,如果我想使用等效的regexp,我会使用\[^,]+.,这比纯基于字符串的要快一点。它们都比正则表达式快一个数量级。。。