0

软件正在生成 UTF-8 文件,但将内容写入非 unicode 文件。我无法更改该软件,必须按现在的样子获取输出。不知道这是否会正确显示在此处,但德语变音符号“ä”在文件中显示为“ä”。

如果我在 Notepad++ 中打开文件,它会告诉我文件是 UTF-8(无 BOM)编码的。现在,如果我在记事本中说“转换为 ANSI”,然后将文件编码切换回 UTF-8(不转换),则文件中的德语变音符号是正确的。如何在 Perl 中实现完全相同的行为?无论我到现在为止尝试过什么,变音符号都变得更糟了。

要重现,请为自己创建一个 UTF-8 编码文件并将内容写入其中:

好,我会试试。创建自己的 UTF-8 文件并将其写入:Männer Schüle Vöogel SüÃ

然后,在 UTF-8 mysql 数据库上,创建一个带有 varchar 字段和 UTF8_unicode 编码的表。现在,使用这个脚本:

use utf8;
use DBI;
use Encode;
if (open FILE, "test.csv") {
  my $db = DBI->connect(
    'DBI:mysql:your_db;host=127.0.0.1;mysql_compression=1', 'root', 'Yourpass',
    { PrintError => 1 }
  );
  my $sql="";
  my $sql = qq{SET NAMES 'utf8';};
  $db->do($sql);
  while (my $line = <FILE>) {
    my $sth = $db->prepare("INSERT IGNORE INTO testtable (testline) VALUES (?);");
    $sth->execute($line);
  }
}

文件的确切内容将被写入数据库。但是,我期望在数据库中的输出是德语变音符号:

Männer Schüler Vögel Süß

那么,我怎样才能正确转换呢?

4

2 回答 2

3

具有讽刺意味的是:在我看来,您所说的软件不是在编写“非 unicode 内容”(这是无意义的)-它对其进行了两次UTF-8 编码。让我们以这个ä字符为例:它在 UTF-8 中由两个字节表示,%C3 %A4. 但是随后该程序中的某些内容决定将这些字节视为 Latin-1 编码:因此它们成为两个单独的字符(最终将被编码为 UTF-8,这就是将保存到文件中的内容)。

我想扭转这种情况的最简单方法是让 Perl 在处理从文件中读取的字符串时认为它使用一系列字节(而不是字符序列)。它可以做得很简单(也很丑陋)...

open my $fh, '<:utf8', $file_name or die $!;
my $string = <$fh>;              # a sequence of characters            
$string = utf8::decode($string); # ... will be considered a sequence of octets
于 2012-07-06T12:42:42.033 回答
1

听起来有些东西正在第二次转换它,假设它类似于 ISO 8859-15,然后将其转换为 UTF-8。您可以通过将 UTF-8 转换为 ISO 8859-15(或任何似乎对您的数据有意义的编码)来扭转这种情况。

http://www.fileformat.info/info/unicode/char/E4/index.htm所示,字节 0xC3 0xA4 是ä. 当被视为 ISO 8859-15(或 8859-1,或 Windows-1252,或许多其他 8 位编码)时,它们显示字符串ä

于 2012-07-06T12:35:24.837 回答