PostgreSQL字符串字符替换

时间:2011-02-11 08:36:09

标签: database regex postgresql

我正在尝试编写一个词汇数据库,用于存储由根和模式组成的单词,我想知道如何创建一个将为我组合根和模式的列,同时忽略没有两者的行已填充SELECT查询的列。

基本上,我有一个来自PostgreSQL DB的输出:

SELECT root, root_i FROM tbl_roots NATURAL JOIN tbl_patterns NATURAL JOIN tbl_patterns_triliteral;

  root   | root_i
---------+--------
 {s,ş,m} | 1u2u3a
 {p,l,t} | 1u2u3a
 {t,m,s} | 1u2u3a
 {n,t,l} | 1u2u3a
 {s,ş,m} | 1a2oi3
 {p,l,t} | 1a2oi3
 {t,m,s} | 1a2oi3
 {n,t,l} | 1a2oi3
 {s,ş,m} | 1o2i3
 {p,l,t} | 1o2i3
 {t,m,s} | 1o2i3
 {n,t,l} | 1o2i3
 {s,ş,m} | a12e3
 {p,l,t} | a12e3
 {t,m,s} | a12e3
 {n,t,l} | a12e3
 {s,ş,m} | 1u2á3
 {p,l,t} | 1u2á3
 {t,m,s} | 1u2á3
 {n,t,l} | 1u2á3
 {s,ş,m} |
 {p,l,t} |
 {t,m,s} |
 {n,t,l} |
 {s,ş,m} | 1e2é3
 {p,l,t} | 1e2é3
 {t,m,s} | 1e2é3
 {n,t,l} | 1e2é3
 {s,ş,m} |
 {p,l,t} |
 {t,m,s} |
 {n,t,l} |
 {s,ş,m} |
 {p,l,t} |
 {t,m,s} |
 {n,t,l} |
 {s,ş,m} |
 {p,l,t} |
 {t,m,s} |
 {n,t,l} |

我希望将其即时转换为类似的内容:

  root   | root_i | word_i
---------+--------+--------
 {s,ş,m} | 1u2u3a | suşuma
 {p,l,t} | 1u2u3a | puluta
 {t,m,s} | 1u2u3a | tumusa
 {n,t,l} | 1u2u3a | nutula
 {s,ş,m} | 1a2oi3 | saşoim
 {p,l,t} | 1a2oi3 | paloit
 {t,m,s} | 1a2oi3 | tamois
 {n,t,l} | 1a2oi3 | natoil
 {s,ş,m} | 1o2i3  | soşim
 {p,l,t} | 1o2i3  | polit
 {t,m,s} | 1o2i3  | tomis
 {n,t,l} | 1o2i3  | notil
 {s,ş,m} | a12e3  | asşem
 {p,l,t} | a12e3  | aplet
 {t,m,s} | a12e3  | atmes
 {n,t,l} | a12e3  | antel
 {s,ş,m} | 1u2á3  | suşám
 {p,l,t} | 1u2á3  | pulát
 {t,m,s} | 1u2á3  | tumás
 {n,t,l} | 1u2á3  | nutál
 {s,ş,m} | 1e2é3  | seşém
 {p,l,t} | 1e2é3  | pelét
 {t,m,s} | 1e2é3  | temés
 {n,t,l} | 1e2é3  | neşél

通过将word列中的数字替换为root_i列中该数字索引中的字符,动态生成root列。我还需要删除两列中没有条目的查询行,以减少输出中的混乱。

任何人都可以帮我设计一个postgres函数来完成字符[]和文本字符串的合并吗?我需要的一点正则表达式不应该复杂,但我不知道如何将它与查询混合,或者更好,将其转换为函数。

2 个答案:

答案 0 :(得分:3)

select
  root,
  root_i,
  translate(root_i, "123", array_to_string(root,'')) as word_i
NATURAL JOIN tbl_patterns
NATURAL JOIN tbl_patterns_triliteral
where root is not null and root_i is not null;

答案 1 :(得分:1)

我必须承认不喜欢在sql / plpgsql函数中做很多字符串操作。 Perl有一个运算符,用于替换生成的替换的regexp匹配,这非常有效:

create or replace function splice_to_word(root text, root_i text)
  returns text strict immutable language plperl as $$
  my $roots = shift;
  my $template = shift;
  $template =~ s{(\d+)}{substr($roots,$1-1,1)}ge;
  return $template;
$$;

postgresql数组似乎没有被翻译成Perl列表,因此我认为根被作为字符串传入,例如:

select root, root_i, splice_to_word(array_to_string(root, ''), root_i) from data