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
のようなメソッドを試し、正規表現も検討しましたが、最終的には、C で記述したであろう関数を記述しました (基本的には、開きかっこと閉じかっこを数えて、テキストを分割する場所を見つけます)。関数は次のとおりです。find()
count()
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またはエレガントな方法があるかどうか、または正規表現を使用してこれを解決するかどうかです。