如果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。
答案 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;
虽然我认为你的例子和你的问题不匹配(姓氏有两个字符。