Как я могу разобрать полные имена людей в имена пользователей в Perl? - PullRequest
4 голосов
/ 18 декабря 2008

Мне нужно преобразовать имя в формате Parisi, Kenneth в формат kparisi.

Кто-нибудь знает, как это сделать в Perl?

Вот некоторые примеры данных, которые являются ненормальными:

Zelleb, Charles F. ,, IV
Эилт, Джон ,, IV
Водс, Чарльз Р., III
Welkt, Craig P. ,, Jr.

Эти конкретные имена должны заканчиваться как czelleb, jeilt, cwoods, cwelkt и т. Д.


У меня есть еще одно условие, разрушающее мое имя строитель

О'Нил, Пол

Пока что ответ Винко Врсаловича работает лучше всего, когда в миксе есть странные / испорченные имена, но этот пример, приведенный выше, получился бы как "шумиха" ... будь проклят ниже Иуды если я не могу получить это о между р и п

Ответы [ 7 ]

7 голосов
/ 18 декабря 2008
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
6 голосов
/ 18 декабря 2008

Я бы начал с фильтрации аномальных данных, чтобы у вас были только обычные имена. Тогда что-то вроде этого должно сделать трюк

$t = "Parisi, Kenneth";
$t =~ s/(.+),\s*(.).*/\l$2\l$1/;
4 голосов
/ 18 декабря 2008

Попробуйте:

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

\w здесь соответствует буквенно-цифровому символу. Если вы хотите быть более конкретным, вместо этого вы можете использовать [a-z] и передать флаг i (без учета регистра):

$name =~ s/([a-z]+)\s([a-z])/$2$1/i;
2 голосов
/ 20 декабря 2008

Это решение, состоящее из одной строки, при условии, что вы сохраняете все имена в файле с именем «names» (по одному в строке), и вы обнаружите повторяющиеся имена как-нибудь позже.

cat names | perl -e 'while(<>) {/^\s*(\S*)?,\s*(\S)/; print lc "$2$1\n";}' | sed s/\'//g
1 голос
/ 20 декабря 2008

Похоже, ваши входные данные разделены запятыми. Для меня самый простой способ сделать это - разделить на компоненты, а затем сгенерировать логин из этого:

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";
}
0 голосов
/ 02 июля 2015

Это должно делать то, что вам нужно

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
0 голосов
/ 23 декабря 2008
    $rowfetch =~ s/['-]//g; #All chars inside the [ ] will be filtered out.
    $rowfetch =~ m/(\w+), ?(.)/;
    $rowfetch = lc($2.$1);

вот как я закончил, используя решение Винко Врсаловича ... внутри цикла while, который проходит через SQL-запрос ... еще раз спасибо vinko

...