如何在 Postgres 9.5 中替换多个特殊字符

How to replace multiple special characters in Postgres 9.5

我有一个 table 包含可能包含特殊字符的名称列表:

id   name
1    Johän
2    Jürgen
3    Janna
4    Üdyr
...

是否有将每个字符替换为另一个特定字符的函数? (不一定是无重音的)。像这样:

SELECT id, function('ä,ü',name,'ae,ue');
Result:

    id   name
    1    Johaen
    2    Juergen
    3    Janna
    4    UEdyr
    ...

没有,没有这个功能。编写优化的 C 扩展可能并不难。但是C语言并不总是必要的。您可以尝试 SQL 或 PLpgSQL 函数:

CREATE OR REPLACE FUNCTION xx(text, text[], text[])
RETURNS text AS $$
   SELECT string_agg(coalesce([array_position(, c)],c),'')
      FROM regexp_split_to_table(,'') g(c)
$$ LANGUAGE sql;

postgres=# select xx('Jürgen', ARRAY['ä','ü'], ARRAY['ae','ue']);
┌─────────┐
│   xx    │
╞═════════╡
│ Juergen │
└─────────┘
(1 row)

在我的电脑上,它在 200 毫秒内完成了 6000 次转换(但我有 PostgreSQL 的开发人员版本 - 它更慢)。

replace()

如果您只想替换一个或几个字符,您可以使用函数 replace(string text, from text, to text) 替换字符串子字符串中的所有匹配项。替换功能可用于将一个字符替换为多个字符。

翻译()

如果您想将一些字母翻译成其他字母,您可以使用函数 translate(string text, from text, to text) 将字符串中与 from 中的字符匹配的任何字符替换为 the from 中的相应字符设置。

一些要玩的数据:

drop table if exists xyz;

create table xyz (
    id serial not null,
    name varchar(30)
);

insert into xyz (name) values
    ('Juhänäo'),
    ('Jürgüen'),
    ('Dannäu'),
    ('Übüdyr');

替换函数示例:

select replace(name, 'ä', 'a') from xyz;

此函数将名称列中的字母 ä 替换为字母 a。 Juhänäo 成为 Juhanao。

select replace(name, 'ä', 'ae') from xyz;

现在它将字母 ä 替换为 ae。

select replace(replace(replace(name, 'ä', 'ae'), 'ü', 'ue'), 'Ü', 'Ue') from xyz;

不太好,但示例中所有 ä 变为 ae,ü 变为 ue,Ü 变为 'Ue'。

update xyz set name = replace(replace(replace(name, 'ä', 'ae'), 'ü', 'ue'), 'Ü', 'Ue');

更改字母并更新行。更新结果如下:

Juhaenaeo
Juergueen
Dannaeu
Uebuedyr

翻译函数示例:

select translate(name, 'ä,ü,Ü', 'a,u,U') from xyz;

将所有字母 ä 翻译成 a,将 ü 翻译成 u,将 Ü 翻译成 U。

update xyz set name = translate(name, 'ä,ü,Ü', 'a,u,U');

更新 table 以便翻译所有预定义的字母并将更改保存到数据库中。更新结果如下:

Juhanao
Jurguen
Dannau
Ubudyr

更多信息:

Replace characters with multi-character strings

Postgresql string functions

如果您在寻找德语字母,那么这很有效:

CREATE OR REPLACE FUNCTION public.udf_transliterate_german(
    german_word character varying)
    RETURNS character varying
    LANGUAGE 'sql'
    COST 100
    VOLATILE PARALLEL UNSAFE
AS $BODY$
SELECT REPLACE(
    REPLACE(
        REPLACE(
            REPLACE(
                REPLACE(
                    REPLACE(
                        REPLACE(
                            REPLACE(german_word,
                                'ä','ae'),
                            'ö','oe' ),
                        'ü','ue'),
                    'ß','ss'),
                'Ä', 'AE'),
            'Ö', 'OE'),
        'Ü', 'UE'),
    'ẞ', 'SS');
$BODY$;

虽然不优雅

避免编写自己的 unaccent 函数。相反,我建议使用 unaccent 扩展名。

create extension unaccent;
select unaccent('Juhänäo');
select unaccent(name) from xyz;

这里是link到Postgres documentation for Unaccent