2010-07-22 57 views
3

我有一些文本文件,我試圖用Windows上的Perl腳本進行轉換。記事本+中的文本文件看起來很正常,但我的腳本中的所有正則表達式都無法匹配。然後我注意到當我在NotePad +中打開文本文件時,狀態欄顯示「UCS-2 Little Endia」(原文如此)。我假設這對應於編碼UCS-2LE。因此,我創建「READFILE」和「WriteFile的」潛艇在Perl,像這樣:Perl中的Unicode不起作用

use PerlIO::encoding; 

my $enc = ':encoding(UCS-2LE)'; 

sub readFile { 
    my ($fName) = @_; 
    open my $f, "<$enc", $fName or die "can't read $fName\n"; 
    local $/; 
    my $txt = <$f>; 
    close $f; 
    return $txt; 
} 

sub writeFile { 
    my ($fName, $txt) = @_; 
    open my $f, ">$enc", $fName or die "can't write $fName\n"; 
    print $f $txt; 
    close $f; 
} 

my $fName = 'someFile.txt'; 

my $txt = readFile $fName; 
# ... transform $txt using s/// ... 
writeFile $fName, $txt; 

現在正則表達式匹配(雖然不經常比我預期的),但輸出包含穿插亞洲尋找字符的長串多餘的字符串正確的文字。我的代碼錯了嗎?或者記事本+編碼錯了?我應該如何繼續?

+0

提供一些測試數據,它的一個附加hexdump都是一個好主意。顯示導致問題的* complete *代碼。如果你不能讓我們重現問題,我們只能推測。 – daxim 2010-07-22 07:40:23

+0

@daxim:這裏的代碼是相當完整的,我無法檢查它的唯一原因是因爲我沒有記事本+編輯器與之比較。猜測這是一個BOM問題。 – 2010-07-22 08:00:59

回答

2

好的,我想通了。問題是由於「open」調用的「encoding ...」參數所做的編碼轉換與Windows上Perl所執行的默認CRLF轉換之間的斷開造成的。看來正在發生的事情是,在輸出之後,LF正在被翻譯成CRLF,之後編碼已經完成,這導致下一行的16位編碼的「奇偶性」丟失。一旦到達下一條線,「平價」就恢復了。這將解釋「長長的亞洲人角色串中穿插着正確文本的長串」......每一行都被搞砸了。

要糾正它,我拿出編碼參數在我的「開放」的呼叫,並增加了一個「binmode」號召,如下:

open my $f, $fName or die "can't read $fName\n"; 
binmode $f, ':raw:encoding(UCS-2LE)'; 

binmode顯然有一個概念,「分層」 I/O處理有點複雜。

我弄不清楚的一件事是如何讓我的CRLF翻譯回來。如果我忽略:raw或add:crlf,則「奇偶性」問題返回。我已經嘗試重新排序,並且無法使其正常工作。

(I加入這作爲單獨的問題:CRLF translation with Unicode in Perl