2012-07-06 52 views
0

软件正在生成UTF-8文件,但将内容写入非unicode文件。我无法更改该软件,必须按照现在的格式输出。不知道这是否会正确显示,但德文变音符号“ä”在文件中显示为“Ô。具有非Unicode内容的Perl 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); 
    } 
} 

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

方式舒勒沃格尔Süß

所以,我怎么能转换对了吗?

+0

有没有这样的事情,“非Unicode文件”。请提供您的输入,工作脚本,当前输出和预期输出的示例,以便人们可以了解您的问题所在。 – 2012-07-06 12:22:47

+0

我用一些代码和示例数据扩展了我的文本。 – Mathias 2012-07-06 12:40:27

+2

题外话:你应该把'prepare'放在while循环之外。您的方式,'准备'是昂贵的,将为您的文件的每一行完成。有关更多信息,请参阅[DBI文档大纲部分](http://search.cpan.org/~timb/DBI/DBI.pm#Outline_Usage)。 – simbabque 2012-07-06 12:48:47

回答

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位编码)时,它们显示字符串ä

+0

这很讽刺。我尝试了很多东西,但总是开始认为“这是utf-8,所以我必须从utf-8转换为其他编码”。但它很简单,也许对我来说简单....这里是我现在使用的,只是从utf8转换到latin1,而且很好用: $ line = encode(“latin1”,decode(“ utf8“,$ line)); – Mathias 2012-07-06 13:43:39

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