【问题标题】:UTF-8 Hebrew encoding and big question marksUTF-8 希伯来语编码和大问号
【发布时间】:2016-06-22 10:50:39
【问题描述】:

看了很多文章还是没看懂

我正在使用从文件中导入文本

$fp = fopen($storagename, 'r');
while ( !feof($fp) ){
    $line = fgets($fp, 2048);
    $delimiter = "\t";
    $data = str_getcsv($line, $delimiter);

    print_r($data);
}

为了正确显示数字和英文字符,我必须使用

str_replace("\x00", '', $data[7])

但现在尝试显示希伯来字符最终看起来像 �

我尝试使用 iconv/mb_convert_encoding/utf8_decode/encode 进行转换 没有任何帮助..

任何帮助都会很棒

【问题讨论】:

  • 您不能只是从文本文件中删除随机字节来显示它,这不是文本编码应该如何工作的。你绝对需要确定文本文件的编码(我猜它可能是 UTF-16 的一些变体),知道你的应用程序的编码并使用适当的转换函数,如 mb_convert_encoding() 或 iconv()。
  • 我没有这个数据,我怎么知道txt文件的编码?
  • 你必须猜。在一个好的编辑器或浏览器中加载它并更改编码,直到它看起来不错。
  • 我打开它看起来不错这不是我的问题...
  • 当我在记事本++中打开文件时,看起来编码是:UCS-2 little Endian

标签: php utf-8 character-encoding


【解决方案1】:

UCS-2 是 UTF-16 的旧版本,因此您可能应该同时尝试这两种方法(自动检测文本编码不是万无一失的工作)。

我们有源编码。我们可以推测目标编码是 UTF-8(因为它是 2016 年的明智选择,而您的问题实际上被标记为 UTF-8)。所以我们有我们需要的一切。

我们应该首先删除非标准的原始字节操作(例如删除str_replace("\x00", '', $data[7]) 和类似代码)。然后我们可以进行适当的转换。如果您使用mb_convert_encoding(),初始方法可能是:

$delimiter = "\t";
$fp = fopen($storagename, 'r');
while ( !feof($fp) ){
    $line = mb_convert_encoding(fgets($fp, 2048), 'UTF-8', 'UCS-2LE');
    $data = str_getcsv($line, $delimiter);
    print_r($data);
}

您可以查看supported encodings的列表。

但是我们这里有一个潜在的问题:没有办法告诉str_getcsv() 文件编码,所以它不太可能识别您的 UCS-2 行结尾。

您可以根据 CSV 文件的大小尝试不同的解决方案。如果它很小,我会立即转换它。不然我看看stream_get_line()

此函数与 fgets() 几乎相同,只是它允许使用标准 \n、\r 和 \r\n 以外的行尾分隔符,并且不返回分隔符本身。

应该是这样的:

$ending = mb_convert_encoding("\n", 'UCS-2LE', 'UTF-8');
$line = mb_convert_encoding(stream_get_line($fp, 2048, $ending), 'UTF-8', 'UCS-2LE');

这应该适用于 Unix 行尾 (\n) 和 Windows 行尾 (\r\n)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-04-28
    • 2016-08-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-23
    相关资源
    最近更新 更多