ISO 8859 1八进制恢复正常字符

时间:2016-01-21 21:25:34

标签: php laravel encoding

我目前正在将旧项目数据库转换为新格式/新数据库。有一些旧数据,可能是由智能手机应用程序逃脱。现在条目看起来像这样:

Tak hur\341 v posteli po pr\341ci a jde se sp\355nkat

现在真正的条目应该是这样的:

Tak hurá v posteli po práci a jde se spinkat

还有像

这样的条目
Som nen\\355 ja len chodiaca kapuc\\341 pra\\u0161iva ignorujuca

似乎不是ISO 8859 1,尤其是\\u0161部分。

我可能会使用任何PHP函数将其转换回可读版本?谢谢!

1 个答案:

答案 0 :(得分:1)

简单的解决方法:

第一个字符串只是八进制iso-8859-1,而第二个字符串是双重削减iso-8859-1,混合了utf-16字符(为什么?现在这就是问题)。下面的代码采用八进制代码,转换为十六进制,将它们打包为二进制,并将它们编码为utf-8。 utf-16代码已经是十六进制,因此它们只被打包并编码为utf-8。

有关字符集的未来信息参考:http://www.fileformat.info/info/charset/index.htm

<?php
        $string = "Tak hur\341 v posteli po pr\341ci a jde se sp\355nkat";
        $string2 = "Som nen\\355 ja len chodiaca kapuc\\341 pra\\u0161iva ignorujuca";

        print decode_str($string2)."<br>";
        print decode_str($string);


        function decode_str($string){
            return utf16_to_utf8(iso_to_utf8($string));
        }

        function iso_to_utf8($string){
            preg_match_all('#\\\\[0-9]{3}#',$string,$matches);

            foreach($matches[0] as $match){
                $char = preg_replace("#(\\\)#","",$match);
                $a = pack("H*" , base_convert($char,8,16));
                $string = preg_replace('#(\\\\)'.$char.'#',$a,$string);
            }
            return mb_convert_encoding($string,"UTF-8","ISO-8859-1");   
        }

        function utf16_to_utf8($string){
            preg_match_all('#\\\u[a-z0-9]{4}#',$string,$matches);

            foreach($matches[0] as $match){
                $char = preg_replace("#\\\\u#","",$match);
                $a = pack("H*" , $char);
                $a = mb_convert_encoding($a,"UTF-8","UTF-16");
                $string = preg_replace('#'.preg_quote($match).'#',$a,$string);
            }

            return $string;
        }

    ?>