如何在 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
如果您在寻找德语字母,那么这很有效:
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;
我有一个 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
如果您在寻找德语字母,那么这很有效:
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;