2012-07-06 47 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