Как правильно обрабатывать STDIN / STDOUT и правильно работать с кодировкой utf8? - PullRequest
4 голосов
/ 28 марта 2020

В моем коде есть символы utf8. Поэтому я делаю:

use utf8;

my $line =  'ЗГ. РАХ. №382 ВIД 03.02.2020Р';
print $line; # Wide character in print at ...

Тогда я подумал, что мой STDOUT должен быть в utf8:

use utf8;
use open IO => ':utf8 :std';

my $line =  'ЗГ. РАХ. №382 ВIД 03.02.2020Р';
print $line; # Wide character in print at ...

Почему, когда я говорю perl, использовать utf8 в то время как мой источник код содержит utf8 символов Я получаю ошибку?

В то же время:

Нет ошибок:

my $line =  'ЗГ. РАХ. №382 ВIД 03.02.2020Р';
print $line;

Нет ошибок:

use open IO => ':utf8 :std';

my $line =  'ЗГ. РАХ. №382 ВIД 03.02.2020Р';
print $line;

Как мне открыть свои файловые дескрипторы и правильно работать с utf8?

UPD
На самом деле у меня есть этот код. Это не соответствует:

use open IO => ':utf8 :std';

my $line =  'ЗГ. РАХ. №382 ВIД 03.02.2020Р';
my @match =  $line =~ m/(вiд|от|від)/i;
print "$line -> $1 \n";

К сожалению, регулярное выражение не соответствует. Вывод:

ЗГ. РАХ. №382 ВIД 03.02.2020Р ->

Затем я добавляю utf8 Прагма:

use utf8;
use open IO => ':utf8 :std';

my $line =  'ЗГ. РАХ. №382 ВIД 03.02.2020Р';
my @match =  $line =~ m/(вiд|от|від)/i;
print "$line -> $1 \n";

Теперь регулярное выражение сопоставляется, но выдается предупреждение

Wide character in print at t2.pl line 17.
ЗГ. РАХ. №382 ВIД 03.02.2020Р -> ВIД

1 Ответ

2 голосов
/ 28 марта 2020

Спасибо @Grinnz в IR C

Следующий код работает:

use utf8;
use open ':encoding(UTF-8)', ':std';

my $line =  'ЗГ. РАХ. №382 ВIД 03.02.2020Р';
my @match =  $line =~ m/(вiд|от|від)/i;
print "$line -> $1 \n";

Замечания: @Grinnz рекомендуется использовать https://metacpan.org/pod/open :: layer , потому что :std is not a layer, it must be its own argument in the list

Также я не должен использовать :utf8 , потому что

ВНИМАНИЕ: Не используйте этот слой для перевода из байтов UTF-8, поскольку он недопустим UTF-8 или двоичные данные приведут к искаженным строкам Perl. Маловероятно, что при использовании для вывода будет выдан неверный UTF-8, хотя вместо этого он будет выдавать UTF-EBCDI C в системах EBCDI C. Уровень: encoding (UTF-8) (дефис значимый) является предпочтительным, поскольку он обеспечит преобразование между действительными байтами UTF-8 и действительными символами Unicode.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...