如何在Perl中将人的全名解析为用户名?

时间:2008-12-18 19:10:08

标签: string perl parsing substring

我需要将Parisi,Kenneth格式的名称转换为kparisi格式。

有没有人知道如何在Perl中执行此操作?

以下是一些异常的示例数据:

Zelleb,Charles F。,, IV
Eilt,John ,, IV
Wods,Charles R。,, III
Welkt,Craig P。,, Jr。

这些特定的名字最终应该是czelleb,jeilt,cwoods,cwelkt等。


我还有一个条件毁了我的名字建造者

奥尼尔,保罗·
到目前为止,Vinko Vrsalovic的答案在奇怪/腐败的名字在混合中时效果最佳,但上面这个例子会被称为“pneil”... id被诅咒如果我不能在p和n之间得到o

,那就低于犹大

7 个答案:

答案 0 :(得分:7)

vinko@parrot:~$ cat genlogname.pl
use strict;
use warnings;

my @list;
push @list, "Zelleb, Charles F.,,IV";
push @list, "Eilt, John,, IV";
push @list, "Woods, Charles R.,,III";
push @list, "Welkt, Craig P.,,Jr.";

for my $name (@list) {
        print gen_logname($name)."\n";
}

sub gen_logname {
        my $n = shift;
        #Filter out unneeded characters
        $n =~ s/['-]//g;
        #This regex will grab the lastname a comma, optionally a space (the 
        #optional space is my addition) and the first char of the name, 
        #which seems to satisfy your condition
        $n =~ m/(\w+), ?(.)/;
        return lc($2.$1);
}
vinko@parrot:~$ perl genlogname.pl
czelleb
jeilt
cwoods
cwelkt

答案 1 :(得分:6)

我首先会过滤异常数据,因此您只有常规名称。那么这样的事情应该可以解决问题

$t = "Parisi, Kenneth";
$t =~ s/(.+),\s*(.).*/\l$2\l$1/;

答案 2 :(得分:4)

尝试:

$name =~ s/(\w+),\s(\w)/$2$1/;
$name = lc $name;

\w此处匹配任何字母数字字符。如果您想要更具体,您也可以使用[a-z]代替,并传递i标志(不区分大小写):

$name =~ s/([a-z]+)\s([a-z])/$2$1/i;

答案 3 :(得分:2)

这是一个单行解决方案,假设您将所有名称存储在名为“names”的文件中(每行一个),稍后您将以某种方式进行重复的名称检测。

cat names | perl -e 'while(<>) {/^\s*(\S*)?,\s*(\S)/; print lc "$2$1\n";}' | sed s/\'//g

答案 4 :(得分:1)

您的输入数据看起来像是逗号分隔的。对我来说,最明智的方法是将其拆分为组件,然后从中生成登录名:

while (<>) {
    chomp;
    my ($last, $first) = split /,/, lc $_;
    $last =~ s/[^a-z]//g;  # strip out nonletters
    $first =~ s/[^a-z]//g; # strip out nonletters
    my $logname = substr($first, 0, 1) . $last;
    print $logname, "\n";
}

答案 5 :(得分:0)

    $rowfetch =~ s/['-]//g; #All chars inside the [ ] will be filtered out.
    $rowfetch =~ m/(\w+), ?(.)/;
    $rowfetch = lc($2.$1);

这就是我最终使用Vinko Vrsalovic的解决方案......它内部循环通过sql查询结果...再次感谢vinko

答案 6 :(得分:0)

这应该做你需要的事情

use strict;
use warnings;
use 5.010;

while ( <DATA> ) {
    say abbreviate($_);
}


sub abbreviate {
    for ( @_ ) {
        s/[-']+//g;
        tr/A-Z/a-z/;
        tr/a-z/ /c;
        return "$2$1" if /([a-z]+)\s+([a-z])/;
    }
}


__DATA__
Zelleb, Charles F.,,IV
Eilt, John,, IV
Woods, Charles R.,,III
Welkt, Craig P.,,Jr.
O'Neil, Paul

输出

czelleb
jeilt
cwoods
cwelkt
poneil