Kiedy nie masz use utf8;
, ale przeglądasz kod za pomocą edytora tekstu utf8, nie widzisz go tak, jak perl go widzi. Myślisz, że masz jedną postać w lewej połowie twojej s///
i tr///
, ale ponieważ jest to wiele bajtów, perl widzi to jako wiele znaków.
Co sądzisz Perl widzi:
my $str1 = "\xE8\xEE\xFC";
my $str2 = $str1;
$str1 =~ tr/\xEE/i/;
print "$str1\n";
$str2 =~ s/\xEE/i/;
print "$str2\n";
Co Perl faktycznie widzi:
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";
Z s///
, ponieważ żaden z bohaterów są operatory wyrażeń regularnych, jesteś po prostu robi wyszukiwania podciąg. Szukasz podłańcucha o wielu znakach. I znajdziesz to, ponieważ to samo, co się wydarzyło w twoim s///
, dzieje się również w twoich literałach ciągów znaków: znaki, które twoim zdaniem są tam naprawdę, nie są, ale wieloliterowa sekwencja jest.
Z kolei w tr///
wiele znaków nie jest traktowanych jako sekwencja, traktowane są one jako zestaw. Każdy znak (bajt) jest traktowany oddzielnie, gdy zostanie znaleziony. A to nie przynosi oczekiwanych rezultatów, ponieważ zmiana poszczególnych bajtów łańcucha utf8 nigdy nie jest tym, czego potrzebujesz.
Fakt, że można uruchomić proste wyszukiwanie podłańcuchowe zorientowane na ASCII, które nic nie wie o utf8 i uzyskać poprawny wynik na ciągu utf8, jest uważane za dobrą kompatybilność wsteczną funkcji utf8, w przeciwieństwie do innych kodowań, takich jak ucs2/utf16 lub ucs4.
Roztwór powiedzieć perl źródłem jest kodowany za pomocą UTF-8 przez dodanie use utf8;
. Będziesz także musiał kodować swoje wyjścia, aby dopasować to, czego oczekuje twój terminal.
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";
Działa również dla mnie, dziękuję. Każdy pomysł, dlaczego "tr" wydaje się potrzebować tych pragm, podczas gdy 's' nie? – Georg
Chciałem tylko powiedzieć coś o łańcuchach znaków i semantykach ciągów bajtowych, ale zobacz odpowiedź @ Wumpusa, myślę, że wyjaśnia to znacznie lepiej. – zoul
@Zoul, cieszę się, że nie zrobiłeś; Nie ma to nic wspólnego z dwoma wewnętrznymi formatami pamięci. – ikegami