【问题标题】:multibyte strtr() -> mb_strtr()多字节 strtr() -> mb_strtr()
【发布时间】:2011-02-15 01:39:21
【问题描述】:

有人写过函数 strtr() 的多字节变体吗?我需要这个。

编辑 1(所需用法示例):

例子: $from = 'ľľščťžýáíŕďňäô'; // 这些字符是 UTF-8 $to = 'llsctzyaiŕdnao'; // 输入 - UTF-8 $str = 'Kŕdeľ ďatľov učí koňa žrať kôru.'; $str = mb_strtr($str, $from, $to); // 输出 - 没有变音符号的 str // $str = 'Krdel datlov uci kona zrat koru.';

【问题讨论】:

  • 您能否提供一个示例来说明您正在尝试做什么(代码示例?)?为特定用例建议替代方案会更容易。
  • 我手头没有确切的例子,但在 phps 文档页面上查看用户 cmets 总是值得的:us3.php.net/strtr 似乎有人已经遇到了同样的问题。也许其中一个已经在那里发布了解决方案。
  • 是的,麦克斯,你是对的。我在那里寻找解决方案,但什么也没找到。
  • @PeterKrauss : mb_strstr()strstr() 的多字节等效项:在另一个字符串中找到第一次出现不是 strtr() : 翻译字符或替换子字符串,所以没有帮助。
  • @megar,操作,抱歉,删除我的评论以避免读者混淆。

标签: php string multibyte


【解决方案1】:

相信 strtr is multi-byte safe,无论哪种方式,因为str_replace 多字节安全,你可以包装它:

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

由于没有mb_str_split 函数,您还需要编写自己的函数(使用mb_substrmb_strlen),或者您可以只使用PHP UTF-8 实现(稍作改动):

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

}

但是,如果您正在寻找从字符串中删除所有(拉丁语?)重音符号的函数,您可能会发现以下函数很有用:

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

【讨论】:

  • @Alix Axel:你是对的。我检查了 strtr 的文档:“如果 from 和 to 的长度不同,则忽略两者中较长的多余字符。str 的长度将与返回值的长度相同。”
  • 一个小改进:在正则表达式中添加“caron”,如下所示:... slash|th|tilde|uml|caron); ...。现在,诸如“Škoda”之类的文本也将不再重音。
  • @bilygates:我去检查了caron 变音符号是否被 PHP 支持,但它仍然没有出现在我的 get_html_translation_table(HTML_ENTITIES) 调用中。您使用的是什么版本的 PHP?你能在那个查找表中看到&...caron; 实体吗?如果没有,htmlentities() 不应该对这些变音符号进行编码,这会使额外的正则表达式查找/替换变得无用。
  • @Alix Axel:将get_html_translation_table(HTML_ENTITIES, ENT_QUOTES, 'UTF-8') 与UTF-8 编码的参数一起使用,您将看到Šš。我正在使用 PHP 5.3.12。干杯!
  • @bilygates:是的,一定是这样,我使用的是 PHP 5.3.2,并且编码参数仅在 PHP 5.3.4 中添加。感谢您回复我。
【解决方案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;
}

【讨论】:

    【解决方案3】:

    可能使用 str_replace 是一个很好的解决方案。另一种选择:

    <?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);
    

    使用 PHP 5.2 在我的机器上打印:

    Original: 
    Kŕdeľ ďatľov učí koňa žrať kôru.
    
    Tranlated: 
    Krdel datlov uci kona zrat kôru.
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-02
      • 2015-04-04
      • 1970-01-01
      相关资源
      最近更新 更多