У вас есть проблемы, потому что вы игнорируете декодировать двоичные данные в строки Perl во время ввода и кодировать строки Perl в двоичные данные во время вывода. Причина этого в том, что регулярные выражения и их друг split
правильно работают со строками Perl.
(?<=.)
означает «после первого символа». Также, эта программа не будет работать правильно на compound / составные фамилии; имейте в виду, что они редки, но существуют. Чтобы всегда правильно разделить имя на фамилию и части имени, вам необходимо использовать словарь с фамилиями.
Версия для Linux:
use strict;
use warnings;
use Encode qw(decode encode);
while (my $full_name = <DATA>) {
$full_name = decode('UTF-8', $full_name);
chomp $full_name;
my ($family_name, $given_name) = split(/(?<=.)/, $full_name, 2);
print encode('UTF-8',
sprintf('The full name is %s, the family name is %s, the given name is %s.', $full_name, $family_name, $given_name)
);
}
__DATA__
张小三
Выход:
The full name is 张小三, the family name is 张, the given name is 小三.
Версия для Windows:
use strict;
use warnings;
use Encode qw(decode encode);
use Encode::HanExtra qw();
while (my $full_name = <DATA>) {
$full_name = decode('GB18030', $full_name);
chomp $full_name;
my ($family_name, $given_name) = split(/(?<=.)/, $full_name, 2);
print encode('GB18030',
sprintf('The full name is %s, the family name is %s, the given name is %s.', $full_name, $family_name, $given_name)
);
}
__DATA__
张小三
Выход:
The full name is 张小三, the family name is 张, the given name is 小三.