SoundexESP

来自 PostgreSQL 维基
跳转到导航跳转到搜索

库代码片段

计算字符串西班牙语音近似值

适用于 PostgreSQL

在 9.0、9.1 上测试。可能在早期版本中也能正常工作。

PL/pgSQL

依赖于


西班牙语音近似值 是一个用来计算西班牙语语音近似码的函数。

音近似算法是为英语编写的,因此不建议在其他语言中使用它。

在我个人的案例中,我需要一个西班牙语版本的 音近似算法,因此,基于 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