Coder Social home page Coder Social logo

deezaster / germanphonetic Goto Github PK

View Code? Open in Web Editor NEW
36.0 7.0 11.0 31 KB

Phonetischer Algorithmus nach dem Kölner Verfahren für PHP, PL/SQL und Kotlin

PHP 31.78% Kotlin 32.77% Dart 35.45%
soundex-ger algorithmus php oracle-pl sql kotlin phonetic german dart

germanphonetic's Introduction

Phonetischer Algorithmus nach dem Kölner Verfahren

Implementationen

  • Oracle PL/SQL: x3m_soundex_ger.sql

  • PHP: x3m_soundex_ger.php

  • Kotlin: PhoneticConverter.kt (Von Steffen Halstrick [email protected])

  • Dart: german_phonetics.kt (Von Steffen Halstrick <[email protected]>)

Einleitung

Die Kölner Phonetik (auch Kölner Verfahren) ist ein phonetischer Algorithmus, der Wörtern nach ihrem Sprachklang eine Zeichenfolge zuordnet, den phonetischen Code. Ziel dieses Verfahrens ist es, gleich klingenden Wörtern den selben Code zuzuordnen, um bei Suchfunktionen eine Ähnlichkeitssuche zu implementieren. Damit ist es beispielsweise möglich, in einer Namensliste Einträge wie "Meier" auch unter anderen Schreibweisen, wie "Maier", "Mayer" oder "Mayr", zu finden.

Die Kölner Phonetik ist, im Vergleich zum bekannteren Russell-Soundex-Verfahren, besser auf die deutsche Sprache abgestimmt. Sie wurde 1969 von Postel veröffentlicht.

Algorithmus

Die Kölner Phonetik bildet jeden Buchstaben eines Wortes auf eine Ziffer zwischen "0" und "8" ab, wobei für die Auswahl der jeweiligen Ziffer maximal ein benachbarter Buchstabe als Kontext benutzt wird. Einige Regeln gelten speziell für den Wortanfang (Anlaut). Auf diese Weise wird ähnlichen Lauten derselbe Code zugeordnet. Die beiden Buchstaben "W" und "V" beispielsweise werden mit der Ziffer "3" codiert. Der phonetische Code für "Wikipedia" lautet "3412". Im Gegensatz zum Soundex-Code ist die Länge des phonetischen Codes nach der Kölner Phonetik nicht beschränkt.

Buchstabe Kontext Code
A, E, I, J, O, U, Y 0
H -
B 1
P nicht vor H 1
D, T nicht vor C, S, Z 2
F, V, W 3
P vor H 3
G, K, Q 4
C im Anlaut vor A, H, K, L, O, Q, R, U, X 4
C vor A, H, K, O, Q, U, X außer nach S, Z 4
X nicht nach C, K, Q 48
L 5
M, N 6
R 7
S, Z 8
C nach S, Z 8
C im Anlaut außer vor A, H, K, L, O, Q, R, U, X 8
C nicht vor A, H, K, O, Q, U, X 8
D, T vor C, S, Z 8
X nach C, K, Q 8

Dass für den Buchstaben "C" die Regel "SC" Vorrang vor der Regel "CH" hat, wurde durch den Zusatz "außer nach S, Z" in Zeile 10 der Tabelle berücksichtigt. Dies wird in der Originalveröffentlichung zwar nicht explizit erwähnt, kann aber aus den dort angeführten Beispielen geschlossen werden (z. B. für "Breschnew" wird als Code "17863" angegeben).

Die Umwandlung eines Wortes erfolgt in 3 Schritten:

  1. Buchstabenweise Kodierung von links nach rechts entsprechend der Umwandlungstabelle.
  2. Entfernen aller mehrfachen Codes.
  3. Entfernen aller Codes "0" außer am Anfang.

Beispiel

Der Name "Müller-Lüdenscheidt" wird folgendermaßen kodiert:

  1. Buchstabenweise Kodierung: 60550750206880022
  2. Entfernen aller mehrfachen Codes: 6050750206802
  3. Entfernen aller Codes "0": 65752682

Code Beispiele

PHP

require_once 'x3m_soundex_ger.php';
$phoneticcode = soundex_ger("Meier");

Oracle PL/SQL

Funktion: SOUNDEX_GER()
Select SOUNDEX_GER('Meier'), SOUNDEX_GER('Meyer') from Dual
Funktion: SOUNDEX_GER_MW()

Die Funktion SOUNDEX_GER_MW() dient als Multi-Word-Wrapper von SOUNDEX_GER(). d.h. Die Funktion bricht den Eingabe-String in einzelne Worte auf und codiert jedes einzelne Wort mit SOUNDEX_GER().

Select SOUNDEX_GER_MW('Mueller Luedenscheidt') from Dual

Die Multi-Word-Funktion ist deshalb wichtig, weil auch schon das im Netz üblicherweise dokumentierte Beispiel Müller-Lüdenscheidt eigentlich falsch gewählt ist. Müller-Lüdenscheidt sind 2 Wörter und damit gibt es 2 Anlaute und 2 Auslaute. Bei diesem Beispiel tritt das nicht zu Tage, aber z.B. bei Heinz Classen (im Unterschied zu HeinzClassen, was nämlich normalerweise kodiert würde). Wird "Heinz Classen" mit der üblichen Implementierung kodiert und dabei ignoriert, dass es sich um 2 Wörter handelt, dann entsteht 068586, wobei Z zu 8 und C ebenfalls zu 8 wird und die zweite 8 entfällt. Wird es als zwei Wörter behandelt, dann wird C zu 4 und bleibt erhalten, also 068 4586.

germanphonetic's People

Contributors

deezaster avatar fonata avatar haenchen avatar hannsen avatar jboockmann avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

germanphonetic's Issues

Code für 'c' als letztes Zeichen falsch.

x3m_soundex_ger.php, Zeile 185:

     case 'c':
        if ($x + 1 < $wordlen) {
           // ...
        } else {
---        $code .= "4";
+++        $code .= "8";
        }

Defaultwert für 'c', wenn sonst keine Regel zutrifft, sollte laut Tabelle eigentlich 8 sein.
(in x3m_soundex_ger.sql ist es korrekt implementiert.)

Fehlerhafte Algorithmusimplementierung Oracle Version

Sehr geehrter Herr Theiler,

bei der Suche nach einer Implementierung der Kölner Phonetik in Oracle bin auf Ihre Funktion im Netz gestoßen:
https://github.com/deezaster/germanphonetic

Eine Frage stellt sich mir allerdings bei der Analyse des Algorithmus: Die Vorgabe bei der Konvertierung lautet ja wie folgt:

  1. Buchstabenweise Kodierung von links nach rechts entsprechend der Umwandlungstabelle.
  2. Entfernen aller mehrfachen Codes.
  3. Entfernen aller Codes "0" außer am Anfang.

Soweit ich sehe, werden aber in Ihrer Funktion SOUNDEX_GER zunächst alle Codes „0“ entfernt und anschließend die Mehrfach-Codes eliminiert, was dann ja bei bestimmten Ausgangswerten zu anderen Codierungen führt.
War diese gewählte Reihenfolge bei der Implementierung gewollt? Prinzipiell würden dadurch ja Silben „verschluckt“, sodass im Endeffekt bei einer Ähnlichkeitssuche Wörter als phonetisch identisch identifiziert werden, die aber laut der Silbenanzahl gar nicht phonetisch ähnlich klingen.

Ich würde mich freuen, wenn Sie mir kurz dazu antworten könnten.

Andreas Roskosch, Software-Entwickler
DATA-PLAN Computer Consulting GmbH
Reichenhainer Straße 34 - 36, 09126 Chemnitz

xx is not encoded correct in sql

The SQL implementaton has in line 169
when substr(Word,intX-1,1) in ('c','k','x') then
The x should be replaced with q (see documentation)
when substr(Word,intX-1,1) in ('c','k','q') then

Absturz, wenn Wort nur aus 1 Buchstaben besteht

Hallo Andy,
ich habe einen Fehler in der function x3m_soundex_ger.php gefunden.

Bei mir trat der seltene Fall auf, dass ich einen Text "mit Vitamin c" hate, auf den ich (Wort für Wort) die Funktion soundex_ger angewendet habe. Wenn ein Wort aber nur aus "c" besteht, dann stürzt die Funktion in Zeile 104 ab, da es bei einem 1-stelligen Wort kein $char[1] gibt...

Oliver Vogel

'scx' sollte '8' liefern, stattdessen kommt aber '848'

Hallo Andy,

es geht um Deine PHP-Implementierung vom Kölner-Phonetik-Algorithmus, die man auf GitHub (https://github.com/deezaster/germanphonetic/blob/master/x3m_soundex_ger.php) finden kann. Vielen Dank für Deine Arbeit, es hat mir sehr geholfen, meine Variante zu testen.
Mir scheint aber, dass es vielleicht in Deiner Funktion einen kleinen Fehler gibt: So, ich glaube, für 'scx' nach dem Algorithmuns sollte '8' kommen, stattdessen kommt aber '848'. Es kann daran liegen, dass es in Zeile 210 (switch für 'x' nach 'c') ein --- break --- fehlt.

Reihenfolgen Entfernen Dopplung und Nullen

Hallo,
im PHP-Code werden zuerst die Nullen und dann die Dopplungen entfernt. Müsste es nicht andersrum sein? Z.B. Röhre ergibt mit dem Code "7", müsste doch aber "77" sein oder liege ich da falsch?

SOUNDEX_GER_MW: Umbruch-Problem

Sehr geehrter Herr Theiler,

Das Problem bei mehrzeiligen Inhalten ist, dass der Umbruch unterschiedlich behandelt werden muss.

Im Normalfall soll er wie ein Worttrennzeichen behandelt werden. Kommt allerdings ein Bindestrich vor dem Umbruch (getrenntes Wort), leitet er kein neues Wort ein.

Beispiel:
Select
soundex_ger_mw('Reit-
stall Müller') A1,
soundex_ger_mw('Reitstall Müller') A2,
soundex_ger_mw('Reitstall
Müller') A3
From
dual

Ergebnis:
A1: 7825 657 //OK
A2: 7825 657 //OK
A3: 7825 //Fehler

Freundliche Grüße
Markus Bauernschmitt

Not all diakritika are converted

In the SQL Version some 'Diakritische Zeichen' like é are encoded, but a lot are missing like óoôîêâ

In Oracle are some functions to change these characters.
One solution coud be to use
utl_raw.cast_to_varchar2(nlssort(, 'nls_sort=binary_ai'))

With this the ß does also not need the replaced manually. The result would be:

   word := regexp_replace(
       utl_raw.cast_to_varchar2(nlssort(
           replace(
               translate(word, 'vwjy', 'ffii'),
           'ph', 'f'),
       'nls_sort=binary_ai')),
   '[^a-z]', ' ');

Problem mit Namen die auf c/k enden können

Hallo,
erstmal vielen Dank für den Code, welcher wirklich gut funktioniert.
Beim testen des Codes sind uns mit Namen, welche sowohl auf c oder k enden können, Probleme aufgefallen.

Yannik -> 064
Yannic -> 068
Dominic -> 2668
Dominik -> 2664

Die Java-Implementierung unter http://lingulist.de/pyjs/demos/kph-demo.html weisst jeweils die gleichen Zahlenwerte als Ergebnis aus.

Haben Sie eine Idee woran das liegt bzw. welche Interpretation korrekt wäre?
Gruß
Jörg Lang

Bindestriche beim MultiwordWrapper als Worttrennung behandeln

Hallo Andy,

zum Kölner Verfahren habe ich einen Änderungsvorschlag, dann ist 'Müller-Lüdenscheid" gleich 'Müller Lüdenscheid': ein Leerzeichen mehr in ...Translate...

in_string := REGEXP_REPLACE(substr(Translate(strWord,'.,-; ',' '),1,4000), '([[:cntrl:]])|(^\t)', ' ');

Gruß
Christoph Gehrke

function changeUnnecessary might be wrong

I don't speak German, but changeUnnecessary might be wrong
text = original.replace(regex1[i], regex2[i])
you see, you iterate over array regex1 and regex2, I think you mean to replace all characters in regex1 to with its counterpart in regex2, then the following code may produce the expected result:
text = text.replace(regex1[i], regex2[i])

Unter welcher Lizenz steht dieser Code?

Wenn man diese Funktion(en) in eigenem Code benutzen und ggf. in anderen (auch Open Source-) Projekten verwenden möchte, müsste man wissen, welche Lizenz hier gilt.

Ich hätte ja einfach die MIT License empfohlen:

The MIT License is a permissive license that is short and to the point. It lets people do anything they want with your code as long as they provide attribution back to you and don’t hold you liable.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.