Ollies Algorithmus war ein guter Anfang, aber er wendete die Markierungen nicht korrekt an. Zum Beispiel wurde qiao1 zu qiao. Dieses Beispiel ist korrekt und vollständig. Sie können leicht erkennen, wie die Ersetzungsregeln definiert sind.
Es macht das Ganze auch für Ton 5, obwohl es keinen Einfluss auf die Ausgabe hat, außer dem Löschen der Nummer. Ich habe es drin gelassen, für den Fall, dass Sie etwas mit Ton 5 machen wollen.
Der Algorithmus funktioniert wie folgt:
- Das Wort und der Ton werden in $match[1] und [2] angegeben.
- Hinter dem Buchstaben, der das Akzentzeichen erhalten soll, wird ein Stern hinzugefügt
- Ein Buchstabe mit einem Stern wird durch den Buchstaben mit der richtigen Tonmarke ersetzt.
Beispiel:
qiao => (iao becomes ia\*o) => qia\*o => qiao
Diese Strategie und der Einsatz von strtr
(das längeren Ersetzungen Vorrang einräumt), sorgt dafür, dass dies nicht passiert:
qiao1 => qiao
function pinyin_addaccents($string) {
# Find words with a number behind them, and replace with callback fn.
return preg_replace_callback(
'~([a-zA-ZüÜ]+)(\d)~',
'pinyin_addaccents_cb',
$string);
}
# Helper callback
function pinyin_addaccents_cb($match) {
static $accentmap = null;
if( $accentmap === null ) {
# Where to place the accent marks
$stars =
'a* e* i* o* u* ü* '.
'A* E* I* O* U* Ü* '.
'a*i a*o e*i ia* ia*o ie* io* iu* '.
'A*I A*O E*I IA* IA*O IE* IO* IU* '.
'o*u ua* ua*i ue* ui* uo* üe* '.
'O*U UA* UA*I UE* UI* UO* ÜE*';
$nostars = str_replace('*', '', $stars);
# Build an array like Array('a' => 'a*') and store statically
$accentmap = array_combine(explode(' ',$nostars), explode(' ', $stars));
unset($stars, $nostars);
}
static $vowels =
Array('a*','e*','i*','o*','u*','ü*','A*','E*','I*','O*','U*','Ü*');
static $pinyin = Array(
1 => Array('a','e','i','o','u','u','A','E','I','O','U','U'),
2 => Array('á','é','í','ó','ú','u','Á','É','Í','Ó','Ú','U'),
3 => Array('a','e','i','o','u','u','A','E','I','O','U','U'),
4 => Array('à','è','ì','ò','ù','u','À','È','Ì','Ò','Ù','U'),
5 => Array('a','e','i','o','u','ü','A','E','I','O','U','Ü')
);
list(,$word,$tone) = $match;
# Add star to vowelcluster
$word = strtr($word, $accentmap);
# Replace starred letter with accented
$word = str_replace($vowels, $pinyin[$tone], $word);
return $word;
}