PostgreSQL 允许在表达式上创建索引,例如CREATE INDEX ON films ((lower(title)))
. 它还具有pg_get_expr()
将表达式的内部格式转换为文本的信息功能,即lower(title)
在前一个示例中。表达有时会变得很毛茸茸。以下是一些示例(在 Python 中):
sample_exprs = [
'lower(c2)',
'lower(c2), lower(c3)',
"btrim(c3, 'x'::text), lower(c2)",
"date_part('month'::text, dt), date_part('day'::text, dt)",
'"substring"(c2, "position"(c2, \'_begin\'::text)), "substring"(c2, "position"(c2, \'_end\'::text))',
"(((c2)::text || ', '::text) || c3), ((c3 || ' '::text) || (c2)::text)",
'f1(f2(arga, f3()), arg1), f4(arg2, f5(argb, argc)), f6(arg3)']
最后一项并不是真正来自 Postgres,而只是我的代码应该处理的一个极端示例。
我编写了一个 Python 函数来将文本列表拆分为组件表达式。例如,最后一项分为:
f1(f2(arga, f3()), arg1)
f4(arg2, f5(argb, argc))
f6(arg3)
我尝试了str
类似find()
and之类的方法count()
,也考虑了正则表达式,但最后我写了一个函数,这就是我用 C 编写的函数(基本上计算打开和关闭括号以找到在哪里中断文本)。这是功能:
def split_exprs(idx_exprs):
keyexprs = []
nopen = nclose = beg = curr = 0
for c in idx_exprs:
curr += 1
if c == '(':
nopen += 1
elif c == ')':
nclose += 1
if nopen > 0 and nopen == nclose:
if idx_exprs[beg] == ',':
beg += 1
if idx_exprs[beg] == ' ':
beg += 1
keyexprs.append(idx_exprs[beg:curr])
beg = curr
nopen = nclose = 0
return keyexprs
问题是是否有更 Pythonic 或更优雅的方式来执行此操作或使用正则表达式来解决此问题。