Я новачок в сценаріях Perl, і я стикаюся з деякими проблемами в розшифровці рядка:
use HTML::Entities;
my $string="Rémunération €";
$string=decode_entitie($string);
print "$string";
Отриманий результат виглядає так Rémunération €
, коли це має виглядати Rémunération €
.
Чи може хто-небудь, будь ласка, допоможіть мені з цим?
Відповіді:
8 для відповіді № 1Якщо ви користуєтеся цією версією коду (з друком в decode_entities
фіксований, строгий режим і попередження увімкнено та додатково print
додано) в терміналі:
use strict;
use warnings;
use HTML::Entities;
my $string="Rémunération €";
print "$stringn";
$string=decode_entities($string);
print "$stringn";
Ви повинні побачити такий вихід:
Rémunération €
Wide character in print at test.pl line 7.
Rémunération €
Що відбувається - це наступний ланцюжок подій:
Ваш код написано utf-8, але не майте
use utf8;
в ньому, тому Perl аналізує ваш вихідний код (і, зокрема, будь-які рядкові літерали в ньому) байт за байтом. Таким чином, рядок буквальний"é"
аналізується як двозначний рядок, тому що кодування utf-8é
займає два байти.Зазвичай це не має значення (багато), тому що ваш
STDOUT
також не знаходиться в режимі utf-8, і тому він просто бере будь-який байт-рядок, який ви йому надаєте, і розпилює його по байтах, а ваш термінал інтерпретує отриманий результат як utf-8 (або намагається).Отже, коли ти робиш
print "é";
Perl думає, що ви "друкуєте двосимвольну рядок у байтовому режимі і виписуєте два байти, які просто трапляються для кодування utf-8 кодування одного символуé
.Однак, коли ви запускаєте рядок наскрізь
decode_entities()
, він розшифровує€
у фактичний Unicode€
символу, який не вміщується всередині одного байта.Коли ви намагаєтеся надрукувати отриманий рядок, Perl помічає "широкий"
€
характер. Він не може друкувати його як єдиний байт, тому замість цього він повертається до кодування весь рядок як utf-8 (і надсилає попередження, якщо вони увімкнено, як слід). Але це викликаєé
s (які були вже закодовані, оскільки Perl ніколи їх не розшифровував під час розбору вашого коду), щоб отримати подвійне кодування UTF8, створюючи моджибаке вихід, який ви бачите.
Просте виправлення - додати use utf8;
до вашого коду, а також встановити всі файлові файли (в тому числі STDIN
/ STDOUT
/ STDERR
) до режиму utf-8 за замовчуванням, наприклад подобається це:
use utf8;
use open qw(:std :utf8);
Якщо ті рядки були попередньо випробуваним сценарієм вище, отриманий результат повинен бути:
Rémunération €
Rémunération €