Khi bạn không có use utf8;
, nhưng bạn đang xem mã bằng trình chỉnh sửa văn bản utf8, bạn sẽ không thấy mã theo cách mà perl nhìn thấy. Bạn nghĩ rằng bạn có một ký tự đơn ở nửa bên trái của s///
và tr///
nhưng vì nó là nhiều byte, perl xem nó là nhiều ký tự.
gì bạn nghĩ perl thấy:
my $str1 = "\xE8\xEE\xFC";
my $str2 = $str1;
$str1 =~ tr/\xEE/i/;
print "$str1\n";
$str2 =~ s/\xEE/i/;
print "$str2\n";
gì perl thực sự thấy:
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";
Với s///
, vì không ai trong số các nhân vật được khai thác regexp, bạn chỉ cần làm một tìm kiếm chuỗi con. Bạn đang tìm chuỗi con đa ký tự. Và bạn tìm thấy nó, bởi vì điều tương tự đã xảy ra trong số s///
của bạn cũng xảy ra trong các chuỗi ký tự của bạn: các ký tự bạn nghĩ là có, nhưng chuỗi ký tự nhiều ký tự là.
Mặt khác, nhiều ký tự không được coi là một chuỗi, chúng được coi là một bộ. Mỗi ký tự (byte) được xử lý riêng khi nó được tìm thấy. Và điều đó không giúp bạn có được kết quả mong muốn, bởi vì việc thay đổi các byte riêng lẻ của chuỗi utf8 không bao giờ là những gì bạn muốn.
Thực tế là bạn có thể chạy tìm kiếm chuỗi con theo định hướng ASCII không biết gì về utf8 và nhận kết quả đúng trên chuỗi utf8, được xem là tính năng tương thích ngược của utf8, trái ngược với các mã hóa khác như ucs2/utf16 hoặc ucs4.
Giải pháp là cho perl biết nguồn được mã hóa bằng UTF-8 bằng cách thêm use utf8;
. Bạn cũng sẽ cần phải mã hóa đầu ra của bạn để phù hợp với những gì thiết bị đầu cuối của bạn mong đợi.
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";
Nguồn
2016-10-23 15:49:17
Nó cũng làm việc cho tôi, cảm ơn bạn. Bất kỳ ý tưởng tại sao 'tr' dường như cần những pragmas, trong khi' s' không? – Georg
Tôi chỉ định nói điều gì đó về chuỗi ký tự so với ngữ nghĩa chuỗi byte, nhưng xem câu trả lời của @ Wumpus, tôi nghĩ nó giải thích vấn đề tốt hơn nhiều. – zoul
@zoul, tôi rất vui khi bạn không làm vậy; Điều này không liên quan gì đến hai định dạng lưu trữ nội bộ. – ikegami