Как разделить китайские иероглифы по одному? - PullRequest
2 голосов
/ 28 апреля 2010

Если между именем и фамилией нет специального символа (например, пробел , : и т. Д.).

Тогда как разделить китайские иероглифы ниже.

use strict; 
use warnings; 
use Data::Dumper;  

my $fh = \*DATA;  
my $fname; # 小三; 
my $lname; # 张 ;
while(my $name = <$fh>)
{

    $name =~ ??? ;
    print $fname"/n";
    print $lname;

}

__DATA__  
张小三

Вывод

小三
张

[Обновить]

WinXP.ActivePerl5.10.1 используется.

Ответы [ 3 ]

3 голосов
/ 28 апреля 2010

У вас есть проблемы, потому что вы игнорируете декодировать двоичные данные в строки 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 小三.
1 голос
/ 28 апреля 2010

Вам понадобится какая-то эвристика для разделения имени и фамилии. Вот некоторый рабочий код, который предполагает, что фамилия (фамилия) - это один символ (первый), а все остальные символы (как минимум один) принадлежат имени (данному имени):

РЕДАКТИРОВАТЬ: Изменена программа, чтобы игнорировать неверные строки, а не смерти.

use strict;
use utf8;

binmode STDOUT, ":utf8";

while (my $name = <DATA>) {
    my ($lname, $fname) = $name =~ /^(\p{Han})(\p{Han}+)$/ or next;
    print "First name: $fname\nLast name: $lname\n";
}

__DATA__  
张小三

Когда я запускаю эту программу из командной строки, я получаю следующий вывод:

First name: 小三
Last name: 张
0 голосов
/ 28 апреля 2010

Это разделяет символы и присваивает им $ fname и $ lname.

my ($fname, $lname) = $name =~ m/ ( \X ) /gx;

Хотя я думаю, что ваш пример и ваш вопрос не совпадают (фамилия состоит из двух символов.

...