4

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

有谁知道如何在 Perl 中做到这一点?

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

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

这些特定名称应以 czelleb、jeilt、cwoods、cwelkt 等结尾。


到目前为止,我还有一个条件正在毁掉我的名字生成器

O'Neil,Paul

,Vinko Vrsalovic 的答案在混合使用奇怪/腐败的名字时效果最好,但上面的这个例子会以“pneil”的形式出现......如果我不能在 p 和 n 之间得到那个 o,我会在犹大之下被诅咒

4

7 回答 7

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
策勒布
投降
乔木
关注
于 2008-12-18T19:27:05.960 回答
6

我将从过滤异常数据开始,以便您只有常规名称。然后像这样的东西应该可以解决问题

$t = "Parisi, Kenneth";
$t =~ s/(.+),\s*(.).*/\l$2\l$1/;
于 2008-12-18T19:18:42.937 回答
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;
于 2008-12-18T19:14:30.107 回答
2

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

cat names | perl -e 'while(<>) {/^\s*(\S*)?,\s*(\S)/; print lc "$2$1\n";}' | sed s/\'//g
于 2008-12-20T00:59:17.253 回答
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";
}
于 2008-12-20T02:53:51.810 回答
0
    $rowfetch =~ s/['-]//g; #All chars inside the [ ] will be filtered out.
    $rowfetch =~ m/(\w+), ?(.)/;
    $rowfetch = lc($2.$1);

这就是我最终使用 Vinko Vrsalovic 解决方案的方式......它在一个遍历 sql 查询结果的 while 循环内......再次感谢 vinko

于 2008-12-23T18:07:34.023 回答
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
于 2015-07-02T15:34:33.410 回答