<?
function unescape($str) {
  $str = rawurldecode($str);
  preg_match_all("/%u.{4}|&#x.{4};|&#\d+;|&#\d+?|.+/U",$str,$r);
  $ar = $r[0];
  foreach($ar as $k=>$v) {
    if(substr($v,0,2) == "%u")
      $ar[$k] = iconv("UCS-2","GBK",pack("H4",substr($v,-4)));
    elseif(substr($v,0,3) == "&#x")
      $ar[$k] = iconv("UCS-2","GBK",pack("H4",substr($v,3,-1)));
    elseif(substr($v,0,2) == "&#") {
      $ar[$k] = iconv("UCS-2","GBK",pack("n",preg_replace("/[^\d]/","",$v)));
    }
  }
  return join("",$ar);
}echo unescape('&#36152&#26131&#32463'); //out 贸易经
?>

解决方案 »

  1.   

    首先谢谢一楼大哥帮我解答与提供思路,不过上面的方法不知什么不能起作用,输出的为空;
    小弟在网上找了以下代码供朋友参考,小弟已经成功应用。原来的代码小弟少作修改:
    $str = "&#36152&#26131&#32463&#27982";echo recode($str);function recode($str){
    $str = preg_replace("|&#([0-9]{1,5})|", "\".u2utf82gb(\\1).\"", $str);
    $str = "\$str=\"$str\";";eval($str);
    return $str;
    }
    function u2utf82gb($c){
        $str="";
        if ($c < 0x80) {
             $str.=$c;
        } else if ($c < 0x800) {
             $str.=chr(0xC0 | $c>>6);
             $str.=chr(0x80 | $c & 0x3F);
        } else if ($c < 0x10000) {
             $str.=chr(0xE0 | $c>>12);
             $str.=chr(0x80 | $c>>6 & 0x3F);
             $str.=chr(0x80 | $c & 0x3F);
        } else if ($c < 0x200000) {
             $str.=chr(0xF0 | $c>>18);
             $str.=chr(0x80 | $c>>12 & 0x3F);
             $str.=chr(0x80 | $c>>6 & 0x3F);
             $str.=chr(0x80 | $c & 0x3F);
        }
        return iconv('UTF-8', 'GB2312', $str);
    }
      

  2.   

    原理就是php处理字串都是按字节来处理的,比如一个汉字占2-3个字节。这一句肯定对。
    把&#36152拆开来,数字对应ascii编码,组合即是汉字了。这一句不知道我说的对不对。
      

  3.   

    呵呵, thunderx(平生一笑) 你怎么想都可以。我给出我找见的答案,只是想让关注这个问题的人也得到解决方法并对他们有帮助。至于我为什么说别人给出的答案不对头,一个是想知道更多思路,另外避免别人浪费时间。我想一楼的老兄也不会介意吧。一楼老兄给出的代码我使用的时候,源代码仍然是这些数字代码。比如一个汉字占2-3个字节....这句肯定不对.把&#36152拆开来,数字对应ascii编码,组合即是汉字了。这一举我也不知道你说的对不对
    一下代码你参考:
    function uc2html($str) {
    $ret='';
    for( $i=0; $i<strlen($str)/2; $i++ ) {

    $charcode = ord($str[$i*2])+256*ord($str[$i*2+1]);
    $ret .= '&#'.$charcode;
    }
    return $ret;

    }输入的$str是直接从excel单元格读取出来的数据,经过处理后就是上面的格式,看起来是把单字节的码值计算后相加得到,至于里面码值原理我不清楚,有没有相关的资料和推荐书籍
    我不懂,但我很想懂。
      

  4.   

    mbstring库里有个函数,去查一下php手册
      

  5.   

    呵呵,一格utf-8编码的汉字占3个字节,我不知道gb编码的汉字字节是怎么算的,所以说是2-3个字节。
    请将下面的代码另存为utf-8编码$ip = "汉";
    uniord2($ip);function uniord2($u) {
       $k = $u;
       $k1 = ord(substr($k, 0, 1));
       $k2 = ord(substr($k, 1, 1));
       $k3 = ord(substr($k, 2, 1));
       $k4 = ord(substr($k, 3, 1));
       $k1 = dechex($k1);$k2 = ten2six($k2);$k3 = ten2six($k3);$k4 = ten2six($k4);   echo "k1 = $k1 k2=$k2 k3=$k3 k4=$k4<br/>\n";
       //return "$k1=$k2=$k3";
    }//end func uniordfunction ten2six($ten){
    $h = intval($ten/16);
    if ($h>9) {
        switch ($h){
    case 10:
    $h="A";
    break;
    case 11:
    $h="B";
    break;
    case 12:
    $h="C";
    break;
    case 13:
    $h="D";
    break;
    case 14:
    $h="E";
    break;
    case 15:
    $h="F";
    break;
    }
    }$e = $ten%16;if ($e>9) {
        switch ($e){
    case 10:
    $e="A";
    break;
    case 11:
    $e="B";
    break;
    case 12:
    $e="C";
    break;
    case 13:
    $e="D";
    break;
    case 14:
    $e="E";
    break;
    case 15:
    $e="F";
    break;
    }
    }return "0x$h$e";
    }//END FUNC
      

  6.   

    “源代码仍然是这些数字代码”???
    呵呵,楼主的iconv不支持 UCS-2 编码?可见你的php版本太低了!常见的unicode编码的ascii表示有以下几种
    %uhhhh
    &#xhhhh;
    &#ddddd;
    其中:h 十六进制数;d 十进制数
    通常以“;”作为编码串的结束符,对于ie6以下的浏览器“;”是不能缺少的无论是用十六进制还是十进制表示,他们都是unicode的编码值。一个短整型数(占两个字节)说句不好听的话,楼主的u2utf82gb($c)还是本人的作品。居然被拿来作为攻击我的武器啦。可见“为人须留三分意,不可全抛一片心”是多么正确的了
      

  7.   

    不过,不明白中间的转换有什么用,以下的代码也输出贸易经function unescape($str) {
      $str = rawurldecode($str);
      return $str;
    }echo unescape('&#36152&#26131&#32463'); //out 贸易经
      

  8.   

    呵呵,唠叨伤心了。
    请教唠叨编码的问题。gbk编码是从0xhhhh到0xhhhhh,编码范围,哪些是汉字,哪些是标点。哪些是汉字库里的符号。这种编码资料应该到哪里获得。-----------
    我对照word里的字符编码,unicode的都是两个字节,为什么php的utf-8编码是三个字节。
      

  9.   

    不过,不明白中间的转换有什么用,以下的代码也输出贸易经function unescape($str) {
      $str = rawurldecode($str);
      return $str;
    }echo unescape('&#36152&#26131&#32463'); //out 贸易经仅这样输出的还是:&#36152&#26131&#32463,只不过浏览器把他转换成“贸易经”显示,“源文件”中并没有变。因为rawurldecode并不处理这样的输入串
    加入rawurldecode的原因可以从函数名(unescape)看出,他是一个与js的unescape完全等效的函数unicode的都是两个字节,为什么php的utf-8编码是三个字节。
    因为编码规则不同嘛
    utf-8编码是一到八个字节,汉字的utf-8编码多是三个字节,但也有两个和四个字节的
      

  10.   

    <?php
    $str = "&#36152&#26131&#32463";
    $str = preg_replace("|&#([0-9]{1,5});|", "\".u2utf82gb(\\1).\"", $str);
    $str = "\$str=\"$str\";";eval($str);
    echo $str;
    function u2utf82gb($c){
        $str="";
        if ($c < 0x80) {
             $str.=$c;
        } else if ($c < 0x800) {
             $str.=chr(0xC0 | $c>>6);
             $str.=chr(0x80 | $c & 0x3F);
        } else if ($c < 0x10000) {
             $str.=chr(0xE0 | $c>>12);
             $str.=chr(0x80 | $c>>6 & 0x3F);
             $str.=chr(0x80 | $c & 0x3F);
        } else if ($c < 0x200000) {
             $str.=chr(0xF0 | $c>>18);
             $str.=chr(0x80 | $c>>12 & 0x3F);
             $str.=chr(0x80 | $c>>6 & 0x3F);
             $str.=chr(0x80 | $c & 0x3F);
        }
        return iconv('UTF-8', 'GB2312', $str);
    }
    ?>
    同样了.大概一个意思.看看吧!!
      

  11.   

    谢谢各位的指导,如果时间允许的话我会吧我后面查阅的编码方面的资料附上的.
    另外,我上面提供的那个函数就是用 WapWeb(大白菜芯)  提供的同一段代码改造过来的。