Archiv verlassen und diese Seite im Standarddesign anzeigen : [gelöst] deutsche Soundex-Implementation
AmicaNoctis 15-10-2009, 11:52 Hallo zusammen,
bevor ich mich jetzt hinsetze und da selbst was programmiere, habe ich natürlich erstmal im Netz gesucht. Es gibt Gerüchte, dass "jemand das schonmal gemacht hat", aber nichts konkretes, wer das war oder wo man das findet.
Vielleicht weiß ja jemand von euch, wo man das finden kann, sei es als PHP- oder als MySQL-Funktion.
Viele Grüße,
Amica
Futter für Google: "Kölner Phonetik php class"
AmicaNoctis 15-10-2009, 12:12 Hallo Combie,
dein Tipp war als Futter für Google zum Glück unbrauchbar, hat aber ein prima Emetikum abgegeben, weil Google es nicht einfach geschluckt, sondern mit noch mehr drumherum wieder ausgespuckt hat ;)
Jedenfalls: Vielen Dank für den Tipp, ich teste es gerade aus. Das Regelwerk sieht dort ja sehr übersichtlich aus. Meine eigenen Vorüberlegungen waren da wahrscheinlich schon zu kompliziert gedacht.
Gruß,
Amica
Egal aus welchem Löchlein es quoll, Hauptsache du konntest den Auswurf weiter verwerten.
AmicaNoctis 15-10-2009, 12:59 Jep, ich hab es noch etwas meinen Bedürfnissen angepasst, weil am Telefon "s-" im Anlaut ähnlich wie "f-" (Sahne/Fahne) und "-er" im Auslaut ähnlich wie "-a" klingt (Scherz/Schatz; aller/Alah).
Schade, dass MySQL nativ kein preg_replace hat. Dann könnte ich es super leicht gleich dort implementieren.
Schade, dass MySQL nativ kein preg_replace hat. Dann könnte ich es super leicht gleich dort implementieren.
Was genau meinst du?
Reguläre Ausdrücke beherrscht MySQL doch zumindest in gewissem Umfang: http://dev.mysql.com/doc/refman/5.1/en/regexp.html
Ja, das wird dich wohl mindestens eine zusätzliche Spalte kosten.
In sqlite würde es per UDF gehen.
Reguläre Ausdrücke beherrscht MySQL doch zumindest in gewissem Umfang
Da dann kein Index mehr genutzt werden kann, wird das eine "teure" Angelegenheit.
AmicaNoctis 15-10-2009, 13:15 Was genau meinst du?
Reguläre Ausdrücke beherrscht MySQL doch zumindest in gewissem Umfang: MySQL :: MySQL 5.1 Reference Manual :: 11.4.2 Regular Expressions (http://dev.mysql.com/doc/refman/5.1/en/regexp.html)
Eigentlich hätte ich es präziser nicht sagen können: ich meine preg_replace. ;) MySQL kann aber nur matchen.
AmicaNoctis 31-10-2009, 04:14 Hallo zusammen,
nachdem ich das Thema eine Weile ruhen lassen musste, hier nun mein Ergebnis: Die Kölner Phonetik als Funktion für MySQL mit leichten Modifikationen, um Undeutlichkeiten am Telefon zu kompensieren:
delimiter |
drop function if exists strip_non_alpha|
drop function if exists soundex_de|
create function strip_non_alpha (string varchar(255))
returns varchar(255) deterministic
begin
declare res varchar(255) default '';
set string = lower(string);
while char_length(string) > 0 do
if string regexp '^[a-zäöüß]' then
set res = concat(res, substr(string, 1, 1));
end if;
set string = substr(string, 2);
end while;
return res;
end|
create function soundex_de (string varchar(255))
returns varchar(255) deterministic
begin
declare res varchar(255) default '';
declare tmp varchar(255) default '';
declare i tinyint unsigned default 1;
set string = strip_non_alpha(string);
while char_length(string) > 0 do
if string regexp '^[0-9]' then
set res = concat(res, substr(string, 1, 1));
set string = substr(string, 2);
elseif string regexp '^[aeijouyäöüÄÖÜ]' then
set res = concat(res, '0');
set string = substr(string, 2);
elseif string regexp '^ph' then
set res = concat(res, '3');
set string = substr(string, 3);
elseif string regexp '^[bp]' then
set res = concat(res, '1');
set string = substr(string, 2);
elseif string regexp '^[dt][csz]' then
set res = concat(res, '8');
set string = substr(string, 3);
elseif string regexp '^[dt]' then
set res = concat(res, '2');
set string = substr(string, 2);
elseif string regexp '^[fvw]' then
set res = concat(res, '3');
set string = substr(string, 2);
elseif string regexp '^[gkq]' then
set res = concat(res, '4');
set string = substr(string, 2);
elseif string regexp '^c[ahkloqrux]' then
set res = concat(res, '4');
set string = substr(string, 2);
elseif string regexp '^[^sz]c[ahkloqrux]' then
set string = concat(substr(string, 1, 1), '4', substr(string, 3));
elseif string regexp '^[^ckq]x+' then
set tmp = substr(string, 1, 1);
set string = substr(string, 3);
while substr(string, 1, 1) = 'x' do
set string = substr(string, 2);
end while;
set string = concat(tmp, 48, string);
elseif string regexp '^l' then
set res = concat(res, '5');
set string = substr(string, 2);
elseif string regexp '^[mn]' then
set res = concat(res, '6');
set string = substr(string, 2);
elseif string regexp '^r' then
set res = concat(res, '7');
set string = substr(string, 2);
elseif string regexp '^[sz]c' then
set string = concat(substr(string, 1, 1), '8', substr(string, 3));
elseif string regexp '^[szß]' then
set res = concat(res, '8');
set string = substr(string, 2);
elseif string regexp '^c[^ahkloqrux]?' then
set res = concat(res, '8');
set string = substr(string, 2);
elseif string regexp '^[ckq]x' then
set string = concat(substr(string, 1, 1), '8', substr(string, 3));
else
set string = substr(string, 2);
end if;
end while;
set res = replace(res, '070', '@');
set res = replace(res, '07', '0');
set res = replace(res, '@', '070'); # improved handling of silent r after vowels
set res = replace(res, '3', '8'); # for phone calls, where F sounds like S
set tmp = '@';
while i <= char_length(res) do
if substr(res, i, 1) = tmp then
set res = concat(substr(res, 1, i - 1), substr(res, i + 1));
else
set tmp = substr(res, i, 1);
set i = i + 1;
end if;
end while;
set res = concat(substr(res, 1, 1), replace(substr(res, 2), '0', ''));
return res;
end|
delimiter ;
Gruß,
Amica
Sollte das nicht eher in die Code-Schnipsel?
TriphunEM 22-01-2010, 07:09 Wie implementier ich das in MySQL, so dass es mir im Query zur Verfügung steht?
Danke
AmicaNoctis 22-01-2010, 07:14 Du willst es implementieren? Ich dachte, das hätte ich schon gemacht? Oder willst du es nur importieren?:
Du wechselst zu dem Schema (bzw. "Datenbank" in MySQL), in dem es zur Verfügung stehen soll und importierst einfach den gesamten Code. Der legt es als Funktion an und die steht dann immer zur Verfügung. Aufgerufen wird es dann z. B. so:
select soundex_de('Meyer');
select soundex_de('Mayer') = soundex_de('Maja');
Einen "sounds like"-Shortcut gibt es natürlich nicht, dafür müsste man den Parser umschreiben. Aber man kann natürlich alles wie im zweiten Beispiel vergleichen.
Gruß,
Amica
|
|