混合编码并使一切成为 UTF-8
Mixed encoding and make everything UTF-8
我有一些文本有不同的编码,例如下面的文本,有 UTF-8 和 ISO-8859-1 的混合编码:
Ù…Øتوای میکس شده و بخش سالم
但是我希望所有这些都变成UTF-8,也就是说剩下UTF-8编码的部分,其他字符串变成UTF-8,例如上面的文字应该输出为:
محتوای میکس شده و بخش سالم
我使用了不同的方法,使用 PHP 中的 iconv
函数并使用以下 class:
https://github.com/neitanod/forceutf8
但是其中 none 给了我正确的输出,并且文本的某些部分总是变成问号,例如 ???????
。
将混合编码无损地转换为 UTF-8 的最佳方法是什么?
编辑:
混合文本的行字节数:
c399e280a6c398c2adc398c2aac399cb86c398c2a7c39bc59220c399e280a6c39bc592c39ac2a9c398c2b320c398c2b4c398c2afc399e280a120d98820d8a8d8aed8b420d8b3d8a7d984d985
正确的文字:
محتوای میکس شده و بخش سالم
关于@Nulled 确认数据来自数据库的回答,我可以确认问题出在您的 table 或数据库编码错误。
我之前遇到过这个问题,在使用此查询获取我的数据之前,我通过强制 database/table 编码来修复它(你需要将它更新为你的 database/table 编码):
SET NAMES latin1;
例如:
$this->db->query('SET NAMES latin1;');
$this->db->query('SELECT * FROM table')->result();
您的字符串的一部分是 Windows-1252 mojibake,这意味着在某些时候 UTF-8 字符串被解释为 Windows-1252 并从错误的假设转换为 UTF-8。这可以通过将字符串从 UTF-8 转码为 Windows-1252 来逆转,这会产生正确的原始 UTF-8 序列。要仅将其应用于混乱的文本子集,您可以使用正则表达式,例如,仅将转换应用于文本的 non-Arabic 部分:
// sample data
$str_hex = 'c399e280a6c398c2adc398c2aac399cb86c398c2a7c39bc59220c399e280a6c39bc592c39ac2a9c398c2b320c398c2b4c398c2afc399e280a120d98820d8a8d8aed8b420d8b3d8a7d984d985';
// actual string
$str = hex2bin($str_hex);
echo 'Messed up: ', $str, PHP_EOL; // Ù…Øتوای میکس شده و بخش سالم
$fixed = preg_replace_callback(
'/\P{Arabic}+/u', // matches non-Arabic sequences
function (array $m) { return iconv('UTF-8', 'Windows-1252', $m[0]); },
$str
);
echo 'Fixed: ', $fixed; // محتوای میکس شده و بخش سالم
在这里搜索了很多问题,并找到了许多“混合编码”解决方案后,none 其中确实适用于我的情况。
但我是这样解决的。最简单的:
Export/Convert 作为 UTF-8 在最新的 Notepad++ 上。它实际上转换了所有行而没有错误,这与许多包相反(例如 iconv 等)。
我有一些文本有不同的编码,例如下面的文本,有 UTF-8 和 ISO-8859-1 的混合编码:
Ù…Øتوای میکس شده و بخش سالم
但是我希望所有这些都变成UTF-8,也就是说剩下UTF-8编码的部分,其他字符串变成UTF-8,例如上面的文字应该输出为:
محتوای میکس شده و بخش سالم
我使用了不同的方法,使用 PHP 中的 iconv
函数并使用以下 class:
https://github.com/neitanod/forceutf8
但是其中 none 给了我正确的输出,并且文本的某些部分总是变成问号,例如 ???????
。
将混合编码无损地转换为 UTF-8 的最佳方法是什么?
编辑:
混合文本的行字节数:
c399e280a6c398c2adc398c2aac399cb86c398c2a7c39bc59220c399e280a6c39bc592c39ac2a9c398c2b320c398c2b4c398c2afc399e280a120d98820d8a8d8aed8b420d8b3d8a7d984d985
正确的文字:
محتوای میکس شده و بخش سالم
关于@Nulled 确认数据来自数据库的回答,我可以确认问题出在您的 table 或数据库编码错误。 我之前遇到过这个问题,在使用此查询获取我的数据之前,我通过强制 database/table 编码来修复它(你需要将它更新为你的 database/table 编码):
SET NAMES latin1;
例如:
$this->db->query('SET NAMES latin1;');
$this->db->query('SELECT * FROM table')->result();
您的字符串的一部分是 Windows-1252 mojibake,这意味着在某些时候 UTF-8 字符串被解释为 Windows-1252 并从错误的假设转换为 UTF-8。这可以通过将字符串从 UTF-8 转码为 Windows-1252 来逆转,这会产生正确的原始 UTF-8 序列。要仅将其应用于混乱的文本子集,您可以使用正则表达式,例如,仅将转换应用于文本的 non-Arabic 部分:
// sample data
$str_hex = 'c399e280a6c398c2adc398c2aac399cb86c398c2a7c39bc59220c399e280a6c39bc592c39ac2a9c398c2b320c398c2b4c398c2afc399e280a120d98820d8a8d8aed8b420d8b3d8a7d984d985';
// actual string
$str = hex2bin($str_hex);
echo 'Messed up: ', $str, PHP_EOL; // Ù…Øتوای میکس شده و بخش سالم
$fixed = preg_replace_callback(
'/\P{Arabic}+/u', // matches non-Arabic sequences
function (array $m) { return iconv('UTF-8', 'Windows-1252', $m[0]); },
$str
);
echo 'Fixed: ', $fixed; // محتوای میکس شده و بخش سالم
在这里搜索了很多问题,并找到了许多“混合编码”解决方案后,none 其中确实适用于我的情况。
但我是这样解决的。最简单的: Export/Convert 作为 UTF-8 在最新的 Notepad++ 上。它实际上转换了所有行而没有错误,这与许多包相反(例如 iconv 等)。