2013-06-12 3 views
0

정규 표현식을 사용하여 Perl v5.10.1을 실행하는 Linux 서버에서 문자열 바꾸기 작업을 수행하려고하는 Windows에서 SHIFT_JIS (일본어) 인코딩 된 CSV 파일 집합이 있습니다.일본어 파일 SHIFT_JIS로 인코딩 된 Perl 파일

여기 내 요구 사항은 다음과 같습니다. Perl 스크립트의 정규 표현식을 사람이 읽을 수 있도록하고 싶습니다. (적어도 일본인에게는) 입니다. 이렇게 : s/北/0/g; 대신에 16 진수 코드 s/\ x {4eba}/0/g로 흩어져 있습니다.

지금은 Windows의 Notepad ++에서 Perl 스크립트를 편집 중이며 csv 데이터 파일에서 Perl 스크립트로 검색해야하는 문자열을 붙여 넣습니다.

나는 아래 다음과 같은 작업 테스트 스크립트가 있습니다

use strict; 
use warnings; 
use utf8; 

open (IN1, "<:encoding(shift_jis)", "${work_dir}/tmp00.csv") or die "Error: tmp00.csv\n"; 
open (OUT1, "+>:encoding(shift_jis)" , "${work_dir}/tmp01.csv") or die "Error: tmp01.csv\n"; 

while (<IN1>) 
{ 
    print $_ . "\n"; 
    chomp; 
    s/北/0/g; 
    s/10:00/9:00/g;  
    print OUT1 "$_\n"; 
}  

close IN1; 
close OUT1; 

이 성공적으로 csv 파일 9:00과 10:00을 대체 할 것이다, 그러나 문제는 (내가 北를 대체 할 수 없습니다입니다 즉. 북쪽)을 0으로 설정하고 utf8을 맨 위에 포함하지 않는 한.

질문 : 그것은 암시하지 않는 한

1) 열린 문서에서, http://perldoc.perl.org/functions/open.html, 나는, 요구 사항으로 사용 UTF8을 보지 않았다?

a) utf8 만 사용했다면 루프의 첫 번째 print 문이 내 xterm 화면에 가비지 문자를 인쇄합니다.

b) open : encoding (shift_jis) 만 호출 한 경우 루프의 첫 번째 print 문은 일본어 문자를 내 xterm 화면에 인쇄하지만 대체는 발생하지 않습니다. utf8을 사용하지 않았다는 경고는 없습니다.

c) a)와 b)를 모두 사용하면이 예제가 작동합니다.

"utf8 사용"은이 Perl 스크립트에서 enoding (shift_jis)으로 open 호출 동작을 어떻게 수정합니까?

2) 인코딩을 지정하지 않고 파일을 열려고 시도했는데 Perl이 파일 문자열을 원시 바이트로 취급하지 않고 스크립트에 붙여 넣은 문자열이 정규 표현식과 일치하면이를 수행 할 수 있습니다. 원본 데이터 파일의 텍스트와 동일한 인코딩 모든 인코딩을 지정하지 않고이 방법으로 파일 이름 바꾸기를 수행 할 수있었습니다 (내 관련 게시물은 여기를 참조하십시오 : Perl Japanese to English filename replacement).

감사합니다.

UPDATES 1

테스트 윈도우 XP에서

일본어에서 파일 이름과 파일의 텍스트를 교체 펄에서 간단한 현지화 샘플을 .csv 데이터 파일 내에서 南 문자를 복사 클립 보드에 복사 한 다음 파일 이름 (예 : 南 .txt)과 파일 내용 (南) 모두로 사용하십시오. 메모장 + +에서 인코딩 UTF-8에서 파일을 읽는 것은 x93xEC을 보여 주며, 아래에서 읽는 것이 SHIFT_JIS 아래에 표시됩니다.

스크립트 :

펄와 리눅스 서버에서 실행됩니다 다음과 같은 펄 스크립트 south.pl를 사용하여 5.10

#!/usr/bin/perl 
use feature qw(say); 

use strict; 
use warnings; 
use utf8; 
use Encode qw(decode encode); 

my $user_dir="/usr/frank"; 
my $work_dir = "${user_dir}/test_south"; 

# forward declare the function prototypes 
sub fileProcess; 

opendir(DIR, ${work_dir}) or die "Cannot open directory " . ${work_dir}; 

# readdir OPTION 1 - shift_jis 
#my @files = map { Encode::decode("shift_jis", $_); } readdir DIR; # Note filename could not be decoded as shift_jis 
#binmode(STDOUT,":encoding(shift_jis)");      

# readdir OPTION 2 - utf8 
my @files = map { Encode::decode("utf8", $_); } readdir DIR; # Note filename could be decoded as utf8 
binmode(STDOUT,":encoding(utf8)");       # setting display to output utf8 

say @files;         

# pass an array reference of files that will be modified 
fileNameTranslate(); 
fileProcess(); 

closedir(DIR); 

exit; 

sub fileNameTranslate 
{ 

    foreach (@files) 
    { 
     my $original_file = $_; 
     #print "original_file: " . "$original_file" . "\n";  
     s/南/south/;  

     my $new_file = $_; 
     # print "new_file: " . "$_" . "\n"; 

     if ($new_file ne $original_file) 
     { 
      print "Rename " . $original_file . " to \n\t" . $new_file . "\n"; 
      rename("${work_dir}/${original_file}", "${work_dir}/${new_file}") or print "Warning: rename failed because: $!\n"; 
     } 
    } 
} 

sub fileProcess 
{ 

    # file process OPTION 3, open file as shift_jis, the search and replace would work 
    # open (IN1, "<:encoding(shift_jis)", "${work_dir}/south.txt") or die "Error: south.txt\n"; 
    # open (OUT1, "+>:encoding(shift_jis)" , "${work_dir}/south1.txt") or die "Error: south1.txt\n"; 

    # file process OPTION 4, open file as utf8, the search and replace would not work 
open (IN1, "<:encoding(utf8)", "${work_dir}/south.txt") or die "Error: south.txt\n"; 
    open (OUT1, "+>:encoding(utf8)" , "${work_dir}/south1.txt") or die "Error: south1.txt\n"; 

    while (<IN1>) 
    { 
     print $_ . "\n"; 
     chomp; 

     s/南/south/g; 


     print OUT1 "$_\n"; 
    } 

    close IN1; 
    close OUT1; 
} 

결과 :

(BAD) 주석 처리 옵션 1과 3 (주석 옵션 2와 4) 설정 : Readdir 인코딩, SHIFT_JIS; ... 파일 이름 교체에 실패 오류 : 파일 열기 인코딩 결과가 SHIFT_JIS UTF8 "\ x93"는 .//south.pl 줄에서 유니 코드로 (68) \ x93

(BAD)를지도하지 않습니다 주석 해제 옵션 2 4 (설명 옵션 1 및 3) 설정 : Readdir 인코딩, utf8; 파일 열기 인코딩 utf8 결과 : 파일 이름 바꾸기가 작동했습니다. south.txt가 생성되었습니다. south1.txt 파일 내용을 바꾸지 못했습니다. 내용이 \ x93()입니다. 오류 : "\ X {FFFD}는"-Ao = (Bx로 {FFFD는} .txt로 ... .//south.pl 라인 (25) 에 shiftjis에 매핑하지 않습니다

(GOOD)의 주석 옵션 2 및 3 (설명 옵션 1 및 4) 설정 : Readdir 인코딩, utf8; 파일 열기 인코딩 SHIFT_JIS 결과 : 파일 이름 바꾸기가 수행 됨, south.txt가 생성됨 South1.txt 파일 내용 대체가 작동했습니다. 내용이 남쪽 인

결론 :

나는 P를 작동하려면, 예를 들어 서로 다른 인코딩 방식을 사용했다 로퍼 리. csv 파일의 내용이 SHIFT_JIS로 인코딩되었으므로 Readdir utf8 및 파일 처리 SHIFT_JIS.

답변

1

시작할 수있는 좋은 곳은 the documentation for the utf8 module입니다. 어떤 말한다 : 당신은 당신의 코드에서 use utf8이없는 경우

The use utf8 pragma tells the Perl parser to allow UTF-8 in the program text in the current lexical scope (allow UTF-EBCDIC on EBCDIC based platforms). The no utf8 pragma tells Perl to switch back to treating the source text as literal bytes in the current lexical scope.

는 다음 펄 컴파일러는 소스 코드가 시스템의 기본 단일 바이트 인코딩에 있다고 가정합니다. 그리고 '北'라는 캐릭터는별로 의미가 없습니다. pragma를 추가하면 코드에 유니 코드 문자가 포함되어 있으며 모든 것이 작동하기 시작합니다.

+0

감사합니다. Dave, UTF-8과 SHIFT_JIS의 차이점을 설명 할 수 있습니까? UTF8은 인코딩 스키마이므로 SHIFT_JIS가 (다른) 인코딩 스키마 인 경우 utf8 pragma를 사용할 때 SHIFT_JIS 문자가 포함 된 소스 스크립트가 더 이상 단일 바이트로 해석되지 않지만 utf8 문자로. 다음으로 open : encoding (SHIFT_JIS)을 호출하면 파일의 문자가 SHIFT_JIS 문자가됩니다. 두 인코딩 체계가 같지 않으면, 어떻게 작동하는지 알 수 없습니다. 위키 피 디아 페이지 SHIFT_JIS에서 그런 경우인지 알 수 없습니다. – frank

+0

파일 이름 바꾸기 및 파일 내용 바꾸기 작업을 위해 사용한 다른 인코딩 체계를 보여주는 예를 업데이트했습니다. – frank

+0

파일 이름의 인코딩은 운영 체제에 의해 결정됩니다. 너는 그것을 바꿀 수 없다. 파일 내용의 인코딩은 파일을 쓰는 사람에 의해 결정됩니다. –