如何逐个拆分汉字?

时间:2010-04-27 23:34:37

标签: perl split character

如果firstname和lastname之间没有特殊字符(例如空格等)。

然后如何分割下面的汉字。

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 个答案:

答案 0 :(得分:3)

您遇到问题,因为您在输入过程中忽略了将二进制数据解码为Perl字符串,并在输出期间将Perl字符串编码为二进制数据。这样做的原因是正则表达式及其朋友split在Perl字符串上正常工作。

(?<=.)表示“在第一个字符之后”。因此,该程序将无法在复名/复合族名称上正常工作;请记住,它们很少见,但确实存在。为了始终正确地将名称拆分为姓氏和名称部分,您需要使用具有姓氏的字典。

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 :(得分:1)

您需要某种启发式方法来分隔名字和姓氏。这里有一些工作代码假定姓氏(姓氏)是一个字符(第一个),所有剩余字符(至少一个)属于第一个名字(给定名称):

编辑:更改程序以忽略无效行而不是死亡。

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: 张

答案 2 :(得分:0)

这会拆分字符并将它们分配给$ fname和$ lname。

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

虽然我认为你的例子和你的问题不匹配(姓氏有两个字符。