SoundexESP
来自 PostgreSQL 维基
跳转到导航跳转到搜索
西班牙语音近似值 是一个用来计算西班牙语语音近似码的函数。
音近似算法是为英语编写的,因此不建议在其他语言中使用它。
在我个人的案例中,我需要一个西班牙语版本的 音近似算法,因此,基于 lfer 的作品 西班牙语音近似值,我制作了西班牙语音近似算法的 PL/pgSQL 版本。
感谢 Grupo Vesica。
希望这能帮助其他人。
-- oliver mazariegos http://www.grupovesica.com
CREATE OR REPLACE FUNCTION soundexesp(input text) RETURNS text
IMMUTABLE STRICT COST 500 LANGUAGE plpgsql
AS $$
DECLARE
soundex text='';
-- para determinar la primera letra
pri_letra text;
resto text;
sustituida text ='';
-- para quitar adyacentes
anterior text;
actual text;
corregido text;
BEGIN
-- devolver null si recibi un string en blanco o con espacios en blanco
if length(trim(input))= 0 then
return null;
end if;
-- 1: LIMPIEZA:
-- pasar a mayuscula, eliminar la letra "H" inicial, los acentos y la enie
-- 'holá coñó' => 'OLA CONO'
input=translate(ltrim(trim(upper(input)),'H'),'ÑÁÉÍÓÚÀÈÌÒÙÜ','NAEIOUAEIOUU');
-- eliminar caracteres no alfabéticos (números, símbolos como &,%,",*,!,+, etc.
input=regexp_replace(input, '[^a-zA-Z]', '', 'g');
-- 2: PRIMERA LETRA ES IMPORTANTE, DEBO ASOCIAR LAS SIMILARES
-- 'vaca' se convierte en 'baca' y 'zapote' se convierte en 'sapote'
-- un fenomeno importante es GE y GI se vuelven JE y JI; CA se vuelve KA, etc
pri_letra =substr(input,1,1);
resto =substr(input,2);
CASE
when pri_letra in ('V') then
sustituida='B';
when pri_letra in ('Z','X') then
sustituida='S';
when pri_letra in ('G') and substr(input,2,1) in ('E','I') then
sustituida='J';
when pri_letra in('C') and substr(input,2,1) not in ('H','E','I') then
sustituida='K';
else
sustituida=pri_letra;
end case;
--corregir el parametro con las consonantes sustituidas:
input=sustituida || resto;
-- 3: corregir "letras compuestas" y volverlas una sola
input=replace(input,'CH','V');
input=replace(input,'QU','K');
input=replace(input,'LL','J');
input=replace(input,'CE','S');
input=replace(input,'CI','S');
input=replace(input,'YA','J');
input=replace(input,'YE','J');
input=replace(input,'YI','J');
input=replace(input,'YO','J');
input=replace(input,'YU','J');
input=replace(input,'GE','J');
input=replace(input,'GI','J');
input=replace(input,'NY','N');
-- para debug: --return input;
-- EMPIEZA EL CALCULO DEL SOUNDEX
-- 4: OBTENER PRIMERA letra
pri_letra=substr(input,1,1);
-- 5: retener el resto del string
resto=substr(input,2);
--6: en el resto del string, quitar vocales y vocales fonéticas
resto=translate(resto,'@AEIOUHWY','@');
--7: convertir las letras foneticamente equivalentes a numeros (esto hace que B sea equivalente a V, C con S y Z, etc.)
resto=translate(resto, 'BPFVCGKSXZDTLMNRQJ', '111122222233455677');
-- así va quedando la cosa
soundex=pri_letra || resto;
--8: eliminar números iguales adyacentes (A11233 se vuelve A123)
anterior=substr(soundex,1,1);
corregido=anterior;
FOR i IN 2 .. length(soundex) LOOP
actual = substr(soundex, i, 1);
IF actual <> anterior THEN
corregido=corregido || actual;
anterior=actual;
END IF;
END LOOP;
-- así va la cosa
soundex=corregido;
-- 9: siempre retornar un string de 4 posiciones
soundex=rpad(soundex,4,'0');
soundex=substr(soundex,1,4);
-- YA ESTUVO
return soundex;
END;
$$
示例
db=#select soundexesp('ordoñez'), soundexesp('ordónez'), soundexesp('ordondes'), soundexesp('karla'), soundexesp('CARLA'); O635 | O635 | O635 | K640 | K640