PehBehBeh

Erfahrungen eines Hobby-Webentwicklers

PHP-Implementierung der Kölner Phonetik

| 7 Kommentare

Im gestrigen Artikel aus der Serie “Exotische PHP-Funktionen” berichtete ich über zwei Funktionen, mit deren Hilfe sich die Ähnlichkeit zweier Zeichenketten bestimmen lässt. In den Kommentaren wurde bereits erwähnt, dass metaphone() und soundex() nicht optimal für die deutsche Sprache geeignet sind. Deshalb hatte ich sowieso schon geplant, heute die Kölner Phonetik vorzustellen. Dabei handelt es sich um einen Algorithmus, der Wörtern eine Zeichenfolge nach ihrem Klang zuordnet.


Implementierung

Da dieser Algorithmus von Haus aus nicht in PHP implementiert ist, muss dies von Hand geschehen. Hierbei kann man auf die Lösung eines Kommentators im PHP Manual zurückgreifen, der die Kölner Phonetik bereits in eine Funktion verpackt hat.

Der Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
<?php
/**
* A function for retrieving the Kölner Phonetik value of a string
*
* As described at http://de.wikipedia.org/wiki/Kölner_Phonetik
* Based on Hans Joachim Postel: Die Kölner Phonetik.
* Ein Verfahren zur Identifizierung von Personennamen auf der
* Grundlage der Gestaltanalyse.
* in: IBM-Nachrichten, 19. Jahrgang, 1969, S. 925-931
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* @package phonetics
* @version 1.0
* @link http://www.einfachmarke.de
* @license GPL 3.0 <http://www.gnu.org/licenses/>
* @copyright  2008 by einfachmarke.de
* @author Nicolas Zimmer <nicolas dot zimmer at einfachmarke.de>
*/
 
function cologne_phon($word) {
    /**
     * @param  string  $word string to be analyzed
     * @return string  $value represents the Kölner Phonetik value
     * @access public
     */
    
    // prepare for processing
    $word = strtolower($word);
    $substitution = array(
        "ä"=>"a",
        "ö"=>"o",
        "ü"=>"u",
        "ß"=>"ss",
        "ph"=>"f"
    );
 
    foreach ($substitution as $letter => $substitution) {
        $word = str_replace($letter,$substitution,$word);
    }
 
    $len = strlen($word);
 
    // Rule for exeptions
    $exceptionsLeading = array(
        4 => array("ca","ch","ck","cl","co","cq","cu","cx"),
        8 => array("dc","ds","dz","tc","ts","tz")
    );
 
    $exceptionsFollowing = array("sc","zc","cx","kx","qx");
 
    //Table for coding
    $codingTable = array(
        0  => array("a", "e", "i", "j", "o", "u", "y"),
        1  => array("b", "p"),
        2  => array("d", "t"),
        3  => array("f", "v", "w"),
        4  => array("c", "g", "k", "q"),
        48 => array("x"),
        5  => array("l"),
        6  => array("m", "n"),
        7  => array("r"),
        8  => array("c", "s", "z"),
    );
 
    for ($i=0; $i<$len; $i++) {
        $value[$i] = "";
 
        //Exceptions
        if ($i == 0 && $word[$i].$word[$i+1] == "cr") {
            $value[$i] = 4;
        }
 
        foreach ($exceptionsLeading as $code => $letters) {
            if (in_array($word[$i].$word[$i+1], $letters)) {
                $value[$i] = $code;
            }
        }
 
        if ($i != 0 && (in_array($word[$i-1].$word[$i], $exceptionsFollowing))) {
            $value[$i] = 8;
        }
 
        // normal encoding
        if ($value[$i] == "") {
            foreach ($codingTable as $code => $letters) {
                if (in_array($word[$i], $letters)) {
                    $value[$i] = $code;
                }
            }
        }
    }
 
    // delete double values
    $len = count($value);
 
    for ($i=1; $i<$len; $i++) {
        if ($value[$i] == $value[$i-1]) {
            $value[$i] = "";
        }
    }
 
    // delete vocals
    for ($i=1; $i>$len; $i++) {
        // omitting first characer code and h
        if ($value[$i] == 0) {
            $value[$i] = "";
        }
    }
    
    $value = array_filter($value);
    $value = implode("", $value);
 
    return $value;
}

Beispiel

Hier noch ein paar Beispiele:

1
2
3
4
echo cologne_phon("Hans"); // 68
echo cologne_phon("Franz"); // 3768
echo cologne_phon("Schokolade"); // 8452
echo cologne_phon("Raddampfer"); // 726137
Dir hat der Artikel gefallen?
Dann abonniere doch den RSS-Feed!