2016-10-23 3 views
11

일부 문자열에서 분음 부호를 제거하고 싶습니다. tr///이 작업을 수행해야하지만 실패합니다 (아래 참조). 인코딩/디코딩 문제가 있다고 생각했지만 s///이 예상대로 작동합니다. 왜 누군가가 설명 할 수 있을까요? 여기 Perl : tr ///가 s ///가 예상 한대로 작동하지 않습니다.

결과의 예입니다 내가 얻을 :

my $str1 = 'èîü'; 
my $str2 = $str1; 
$str1 =~ tr/î/i/; 
print "$str1\n"; # => i�iii� 
$str2 =~ s/î/i/; 
print "$str2\n"; # => èiü 

tr///는 문자열뿐 아니라 중간 하나의 첫 번째와 세 번째 문자를 수정하는 것으로.

편집 : 메이트 데스크탑 환경에서 우분투 16.04를 사용합니다. 나를 위해 예상대로이 작동

답변

18

use utf8;이 없지만 utf8 텍스트 편집기로 코드를보고있는 경우 펄에서 보는 방식대로 표시되지 않습니다. s///tr///의 왼쪽 절반에 하나의 문자가 있다고 생각하지만 여러 바이트이기 때문에 perl은 여러 문자로 간주합니다.

당신은 펄이보고 생각하는 것 :

my $str1 = "\xE8\xEE\xFC"; 
my $str2 = $str1; 
$str1 =~ tr/\xEE/i/; 
print "$str1\n"; 
$str2 =~ s/\xEE/i/; 
print "$str2\n"; 

무엇 펄 실제로보고 : s///

my $str1 = "\xC3\xA8\xC3\xAE\xC3\xBC"; 
my $str2 = $str1; 
$str1 =~ tr/\xC3\xAE/i/; 
print "$str1\n"; 
$str2 =~ s/\xC3\xAE/i/; 
print "$str2\n"; 

, 문자 것도 정규 표현식 연산자 없기 때문에, 당신은 단지 문자열 검색을 수행하고 있습니다. 여러 문자로 된 하위 문자열을 검색하고 있습니다. s///에서 일어난 똑같은 일이 문자열 리터럴에서도 일어나기 때문에 찾을 수 있습니다. 실제로 거기에있는 문자는 실제로는 아니지만 복수 문자 시퀀스 입니다.

반면에 tr///에서는 여러 문자가 시퀀스로 처리되지 않고 집합으로 처리됩니다. 각 문자 (바이트)는 발견되면 따로 처리됩니다. 그리고 utf8 문자열의 개별 바이트를 변경하면 원하는 결과가 나오지 않으므로 원하는 결과를 얻을 수 없습니다.

utf8에 대해 아무것도 모르는 간단한 ASCII 지향적 부분 문자열 검색을 실행하고 utf8 문자열에서 올바른 결과를 얻는 것은 ucs2와 같은 다른 인코딩과는 달리 utf8의 좋은 하위 호환성 기능으로 간주됩니다/utf16 또는 ucs4.


use utf8; 용액을 첨가하여 소스 UTF-8을 사용하여 인코딩 펄 알 것이다. 또한 터미널에서 기대하는 것과 일치하도록 출력물을 인코딩해야합니다.

use utf8;        # The source is encoded using UTF-8. 
use open ':std', ':encoding(UTF-8)'; # The terminal provides/expects UTF-8. 
my $str1 = 'èîü'; 
my $str2 = $str1; 
$str1 =~ tr/î/i/; 
print "$str1\n"; 
$str2 =~ s/î/i/; 
print "$str2\n"; 
3

:

use v5.10; 
use utf8; 
use open qw/:std :utf8/; 

my $str1 = 'èîü'; 
my $str2 = $str1; 
$str1 =~ tr/î/i/; 
say $str1; # èiü 
$str2 =~ s/î/i/; 
say $str2; # èiü 

use utf8 pragma는 UTF-8 소스 코드에 리터럴 수는 use open pragma는 UTF-8로 STDOUT을 전환합니다.

+0

제게도 효과가 있습니다. 감사합니다. 'tr'이 pragma를 필요로하는 이유는 무엇입니까? – Georg

+4

나는 단지 문자열 대 바이트 문자열의 의미에 대해 말하려고했으나 @ Wumpus의 대답을 보았다. 문제를 훨씬 잘 설명한다고 생각한다. – zoul

+0

@zoul, 당신이하지 않았기 때문에 기쁩니다. 이것은 두 가지 내부 저장 형식과 아무 관련이 없습니다. – ikegami