MenuIcon

Owl-Networks Archive

LoginIcon

Perl / Encode : UTF-8 + BOM 문서를 decode 할 때 주의할 점

| 분류: Perl | 최초 작성: 2011-11-12 06:54:24 |

Perl 5.10 혹은 그 이전 버전에서 모두 발생합니다. 그 이후의 버전은 저도 모릅니다.


Perl의 Encode 모듈에서 decode 함수를 사용할 때, 만약 읽어들이는 문서가 UTF-8 문서라면 주의해야 한다. UTF-8의 경우 굳이 BOM(Byte Order Mark)을 붙이지 않아도 상관이 없는데, 일부 UTF-8 문서의 경우 UTF-8 인코딩을 사용하면서도 BOM이 붙어 있다. (예를 들면, 윈도우의 메모장으로 적성 후 UTF-8 인코딩 문서로 저장한 경우, 자동으로 BOM 이 포함되어 저장된다.)

이 문서를 Perl에서 읽을 경우, decode 되는 과정에서 decode 모듈이 이 BOM을 제거하지 않고 남겨두므로, 이 문자로 인하여 예상치 못한 문제가 발생할 수 있다. (문자열 처리 과정에서 필연적으로 오류를 만나게 된다!) 따라서 UTF-8 문서를 읽을 때에는, decode 한 후에 이 BOM 문자를 날려주는 작업이 별도로 이루어져야 한다.

sub FileRead {

my $RAW_DATA;
my $ENCODING;

open my $fHandle, "<", "$_[0]";
binmode $fHandle;
while(<$fHandle>){
$RAW_DATA .= $_;
}
close $fHandle;
undef $fHandle;

#------------------------

use Encode;
use Encode::Guess;

my $enc = guess_encoding($RAW_DATA, qw/ascii euc-kr utf8/);

if ( ref($enc) ) {
$ENCODING = $enc->name;
}
else {
$ENCODING = "Unknown";
}

undef $enc;

#------------------------

if ( $ENCODING eq "Unknown" ) {

print "Unknown Encoding!";
return -1;
}
else {

$RAW_DATA = decode( $ENCODING, $RAW_DATA );
}

# UTF8+BOM 주의

if ( $ENCODING eq "utf8" ) {
$RAW_DATA =~ s/\x{FEFF}//g;
}

undef $ENCODING;

#------------------------

return $RAW_DATA;
}


참고로, 역시 BOM이 붙어있는 UTF-16 (윈도우에서 기본으로 사용하는 유니코드. UTF-16 BE(Big Endian)와 UTF-16 LE(Little Endian)이 있으며, 윈도우는 후자를 사용한다.) 의 경우에는 decode 모듈이 자동으로 BOM을 날려주기 때문에, 위와 같은 번거로운 처리가 필요 없다.

* http://perldoc.perl.org/5.10.1/Encode/Guess.html

이 문서의 중간쯤에 관련 경고가 기술되어 있다 - "CAVEAT: Unlike UTF-(16|32), BOM in utf8 is NOT AUTOMATICALLY STRIPPED."

왜 잘 들여다보지도 않는 Guess 모듈 한구석에 적어놓은건지...

☞ 태그: Perl, Byte Order Mark, BOM, Encode,

☞ 트랙백 접수 모듈이 설치되지 않았습니다.

☞ 덧글이 없고, 트랙백이 없습니다.

덧글을 남기시려면 여기를 클릭하십시오.
[483] < [410] [408] [407] [406] [405] ... [403] ... [402] [400] [398] [394] [392] > [19]

(C) 2000-2018, Owl-Networks. Powered by Perl. 이 페이지는 HTML 5 표준에 따라 작성되었습니다.