我以这种方式连接了字符串替换:
CREATE OR REPLACE FUNCTION norm(t text) RETURNS text AS $$
declare t1 text;
declare t2 text;
...
declare t10 text;
BEGIN
select replace (lower(t), ',', ' ') into t1;
select regexp_replace (t1, '[^0-9a-z\s-]', '', 'g') into t2;
...
select regexp_replace (t10, 'n?oise?.*', '', 'g') into t10;
RETURN trim(t10);
END;
$$ LANGUAGE plpgsql;
目前它有 10 个不同的操作,并且这个数字还在不断增长。此外,将位置更改为转换强制重命名变量也很不方便。
有没有更好的方法来处理这种情况?
与
plperlu
和Regexp::Assemble
这取决于字符串的长度和输入的长度。您可以使用Perl 的 Regexp::Assemble创建完全优化的正则表达式,并使用 plperlu 运行它。
下面的代码缓存整个会话的正则表达式,因此后续调用应该很快。
现在你可以调用它,
或者,您可以在其中对正则表达式进行硬核处理,但如果您打算这样做,您也可以砍掉
Regexp::Assemble
,然后粘贴一个预编译的正则表达式。和
plperl
速度
对于这个例子,我采用了以下 300,000 行的示例数据
相比之下,@joanolo 的上述版本需要 8.04 秒
使用 plperl,
需要 5.0 秒。
你可以通过一张
replacements
桌子来帮助自己:您将填充您需要执行的尽可能多的替换:
然后更改您的功能以使用它:
并检查结果:
这不会像硬编码函数中的所有更改那样快,但会提供最高的灵活性。
作为替代方案,您可以只更改函数的代码结构,并多次重复使用同一个变量1:
如果替换数量适中,这会更快,并且是最好的选择。
您可以在dbfiddle此处查看
1) PLPGSQL 不是一种强制你只给
val
s 赋值一次的函数式语言,变量可以根据需要被覆盖多次。如果你用Scala的术语来思考,它们是var
s,而不是val
s。用 Java 术语来说,它们不是immutable
.