我正在使用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?如果是这样,正则表达式会是什么样子?
答案 0 :(得分:11)
正则表达式不适合解析“嵌套”结构。相反,请尝试使用完整的解析工具包,例如pyparsing - 例如,可以找到专门用于解析SQL的pyparsing的示例here和here(毫无疑问)需要以示例为出发点,并编写一些自己的解析代码,但是,这绝对不是太难)。
答案 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'。
当然,这不是一般解决方案,但是......