2010-07-22 7 views
3

Windows의 Perl 스크립트로 변환하려고하는 텍스트 파일이 있습니다. 텍스트 파일은 메모장 +에서 정상적으로 보이지만 스크립트의 모든 정규식은 일치하지 않습니다. 그런 다음 메모장 +에서 텍스트 파일을 열면 상태 표시 줄에 "UCS-2 Little Endia"라고 표시됩니다. 이 인코딩은 UCS-2LE에 해당한다고 가정합니다. 그래서, 펄에서 "ReadFile을"과 "의 WriteFile"잠수함을 만들었 그래서 같은 : 이제Perl의 유니 코드가 작동하지 않습니다.

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

몇 가지 테스트 데이터를 제공, 그것의 추가 16 진 덤프는 것이 좋습니다. 문제를 일으키는 * 완전한 * 코드를 표시하십시오. 문제를 재현 할 수 없으면 추측 할 수 있습니다. – daxim

+0

@ daxim :이 코드는 합리적으로 완벽합니다. 비교할 메모장 + 편집기가 없기 때문에 내가 확인할 수없는 유일한 이유가 있습니다. 짐작할 때 그것은 BOM 문제입니다. –

답변

2

좋아요, 알아 냈습니다. 이 문제는 "open"호출의 "encoding ..."매개 변수에 의한 인코딩 변환과 Windows의 Perl이 수행 한 기본 CRLF 변환 간의 연결 해제로 인해 발생했습니다. 무슨 일이 일어 났는지는 이후에 LF가 출력 에서 CRLF로 변환되었고, 다음 줄에 대한 16 비트 인코딩의 "패리티"를 제거한 인코딩이 완료된 것입니다. 다음 줄에 도달하면 "패리티"가 되돌아옵니다. 그것은 "긴 문장의 정확한 텍스트"가 산재 해있는 아시아 인의 등장 인물을 설명 할 것이다. 다음과 같이

이 문제를 해결하려면, 내가, 내 "열기"호출에서 인코딩 매개 변수를 꺼내서는 "bin 파일 모드로"전화를 추가 :

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

binmode 분명히의 개념이 "계층"I/O 취급은 다소 복잡합니다.

내가 알 수없는 한 가지는 내 CRLF 번역을 다시받는 방법입니다. 나가 버리면 : raw 또는 add : crlf, "패리티"문제가 반환됩니다. 나는 다시 순서를 매기려고했는데 제대로 작동하지 않는다.

(나는 별도의 질문으로 이것을 추가 : CRLF translation with Unicode in Perl)

관련 문제