软件正在生成UTF-8文件,但是将内容写入不是unicode的文件。我不能改变那个软件,必须像现在一样采取输出。不知道这是否会在这里正确显示,但是文件中显示德语变音符号“ä”为“¤”。
如果我在Notepad ++中打开文件,它会告诉我文件是UTF-8(没有BOM)编码。现在,如果我在记事本中说“转换为ANSI”,然后将文件编码切换回UTF-8(不进行转换),则文件中的德语变音是正确的。如何在Perl中实现完全相同的行为?无论我到现在为止做了什么,破旧的混乱都变得更糟。
要重现,请创建一个UTF-8编码文件并将内容写入其中:
好的,我会试试。创建一个UTF-8文件并将其写入: MännerSchüleVöogelSüÃ
然后,在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ännerSchülerVögelSüß
那么,我该如何正确转换呢?
答案 0 :(得分: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
答案 1 :(得分:1)
听起来像第二次转换它,假设它像ISO 8859-15,然后转换为UTF-8。您可以通过将UTF-8转换为ISO 8859-15(或任何编码似乎对您的数据有意义)来反转这一点。
如http://www.fileformat.info/info/unicode/char/E4/index.htm所示,字节0xC3 0xA4是ä
的有效UTF-8编码。当被视为ISO 8859-15(或8859-1,或Windows-1252,或许多其他8位编码)时,它们显示字符串ä
。