2010-05-03 3 views
11

Hat jemand Multibyte-Variante der Funktion strtr() geschrieben? Ich brauche diesen.multibyte strtr() -> mb_strtr()

Edit 1 (Beispiel der gewünschten Nutzung):

 
Example: 
$from = 'ľľščťžýáíŕďňäô'; // these chars are in UTF-8 
$to = 'llsctzyaiŕdnao'; 

// input - in UTF-8 
$str = 'Kŕdeľ ďatľov učí koňa žrať kôru.'; 
$str = mb_strtr($str, $from, $to); 

// output - str without diacritic 
// $str = 'Krdel datlov uci kona zrat koru.'; 
+2

Könnten Sie vielleicht ein Beispiel für das, was Sie versuchen, genau das zu tun (Codebeispiel?)? Es wäre einfacher, eine Alternative für einen bestimmten Anwendungsfall vorzuschlagen. – Max

+0

Ich habe kein genaues Beispiel zur Hand, aber es ist immer einen Blick auf die Benutzerkommentare auf der PHP-Dokumentationsseite zu werfen: http://us3.php.net/strtr Es scheint, dass es Leute gibt, die bereits das gleiche Problem hatten . Vielleicht hat einer von ihnen die Lösung bereits dort gepostet. – Max

+0

Ja, Max, du hast Recht. Ich suchte nach einer Lösung, aber ich fand nichts. – Martin

Antwort

22

I strtr is multi-byte safe glauben, so oder so, da str_replaceist multibytesicher Sie könnte es wickeln:

function mb_strtr($str, $from, $to) 
{ 
    return str_replace(mb_str_split($from), mb_str_split($to), $str); 
} 

Da es keine mb_str_split Funktion gibt, müssen Sie auch Ihre eigene schreiben (mit mb_substr und mb_strlen), oder Sie könnten nur die PHP UTF-8 Implementierung verwenden (leicht verändert):

function mb_str_split($str) { 
    return preg_split('~~u', $str, null, PREG_SPLIT_NO_EMPTY);; 

} 

Allerdings, wenn Sie für eine Funktion sind alle auf der Suche (latein) Akzentuierungen aus einer Zeichenfolge entfernen Sie den folgenden finden könnten? Funktion nützlich:

function Unaccent($string) 
{ 
    return preg_replace('~&([a-z]{1,2})(?:acute|cedil|circ|grave|lig|orn|ring|slash|th|tilde|uml|caron);~i', '$1', htmlentities($string, ENT_QUOTES, 'UTF-8')); 
} 

echo Unaccent('ľľščťžýáíŕďňä'); // llsctzyairdna 
echo Unaccent('Iñtërnâtiônàlizætiøn'); // Internationalizaetion 
+0

Es gibt keine Funktion mb_str_split – Max

+0

@Max: In der Tat war ich noch nicht fertig mit meiner Antwort. –

+0

Dies funktioniert nicht korrekt für alle Zeichenfolgen. Zum Beispiel echo mb_strtr ("a", "a'.unichr (769)," b "); wird b angezeigt, während ich erwarten würde, dass ein seit unichr (769) nicht in der ursprünglichen Zeichenfolge ist. – BertR

1

Wahrscheinlich mit str_replace ist eine gute Lösung. Eine Alternative:

<?php 
header('Content-Type: text/plain;charset=utf-8'); 

function my_strtr($inputStr, $from, $to, $encoding = 'UTF-8') { 
     $inputStrLength = mb_strlen($inputStr, $encoding); 

     $translated = ''; 

     for($i = 0; $i < $inputStrLength; $i++) { 
       $currentChar = mb_substr($inputStr, $i, 1, $encoding); 

       $translatedCharPos = mb_strpos($from, $currentChar, 0, $encoding); 

       if($translatedCharPos === false) { 
         $translated .= $currentChar; 
       } 
       else { 
         $translated .= mb_substr($to, $translatedCharPos, 1, $encoding); 
       } 
     } 

     return $translated; 
} 


$from = 'ľľščťžýáíŕďňä'; // these chars are in UTF-8 
$to = 'llsctzyairdna'; 

// input - in UTF-8 
$str = 'Kŕdeľ ďatľov učí koňa žrať kôru.'; 

print 'Original: '; 
print chr(10); 
print $str; 

print chr(10); 
print chr(10); 

print 'Tranlated: '; 
print chr(10); 
print my_strtr($str, $from, $to); 

Drucke auf meinem Rechner mit PHP 5.2:

Original: 
Kŕdeľ ďatľov učí koňa žrať kôru. 

Tranlated: 
Krdel datlov uci kona zrat kôru. 
2
function mb_strtr($str,$map,$enc){ 
$out=""; 
$strLn=mb_strlen($str,$enc); 
$maxKeyLn=1; 
foreach($map as $key=>$val){ 
    $keyLn=mb_strlen($key,$enc); 
    if($keyLn>$maxKeyLn){ 
     $maxKeyLn=$keyLn; 
    } 
} 
for($offset=0; $offset<$strLn;){ 
    for($ln=$maxKeyLn; $ln>=1; $ln--){ 
     $cmp=mb_substr($str,$offset,$ln,$enc); 
     if(isset($map[$cmp])){ 
      $out.=$map[$cmp]; 
      $offset+=$ln; 
      continue 2; 
     } 
    } 
    $out.=mb_substr($str,$offset,1,$enc); 
    $offset++; 
} 
return $out; 
} 
Verwandte Themen