Когда у вас нет use utf8;
, но вы просматриваете код в текстовом редакторе utf8, вы видите его не так, как его видит perl. Вы думаете, что у вас есть один символ в левой половине ваших s///
и tr///
, но поскольку это несколько байтов, perl видит их как несколько символов.
Как вы думаете, perl видит:
my $str1 = "\xE8\xEE\xFC";
my $str2 = $str1;
$str1 =~ tr/\xEE/i/;
print "$str1\n";
$str2 =~ s/\xEE/i/;
print "$str2\n";
Что на самом деле видит Perl:
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///
, поскольку ни один из символов не является оператором регулярного выражения, вы просто выполняете поиск подстроки. Вы ищете многосимвольную подстроку. И вы его находите, потому что то же самое, что произошло в вашем s///
, также происходит и в ваших строковых литералах: символы, которые, по вашему мнению, там есть, на самом деле ими не являются, а многосимвольная последовательность есть.
С другой стороны, в tr///
несколько символов рассматриваются не как последовательность, а как набор. Каждый символ (байт) обрабатывается отдельно, когда он найден. И это не дает вам желаемых результатов, потому что изменение отдельных байтов строки utf8 никогда не является тем, чего вы хотите.
Тот факт, что вы можете запустить простой ASCII-ориентированный поиск подстроки, который ничего не знает о utf8, и получить правильный результат для строки utf8, считается хорошей функцией обратной совместимости utf8, в отличие от других кодировок, таких как ucs2/utf16 или ucs4. .
Решение состоит в том, чтобы сообщить Perl, что исходный код закодирован с использованием UTF-8, добавив use utf8;
. Вам также нужно будет закодировать свои выходные данные, чтобы они соответствовали ожиданиям вашего терминала.
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";
person
Community
schedule
23.10.2016