views:

516

answers:

6

I need to convert a name in the format Parisi, Kenneth into the format kparisi.
Does anyone know how to do this in Perl?

Here is some sample data that is abnormal:

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

These specific names should end up as czelleb, jeilt, cwoods, cwelkt... etc

ADDITION+++++

Thanks for all the good answers! I have one more condition that is ruining my name builder

O'Neil, Paul

so far, Vinko Vrsalovic's answer is working the best when weird/corrupt names are in the mix, but this example above would come out as "pneil"... id be damned below judas if i cant get that o between the p and the n

+4  A: 

Try:

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

\w here matches an alphanumerical character. If you want to be more specific, you could also use [a-z] instead, and pass the i flag (case insensitive):

$name =~ s/([a-z]+)\s([a-z])/$2$1/i;
Konrad Rudolph
Konrad, you had it backwards - it's supposed to be the whole last name (which comes first) and then the first initial (which comes second)
Paul Tomblin
Ouch. Thanks for correcting it, Paul. I actually tested the code before posting but somehow I was satisfied with my wrong result. ;-)
Konrad Rudolph
Sorry to say it, but you're no Jon Skeet. :-)
Paul Tomblin
yeah i just tested it also... it looked close, but i didnt get the goods
CheeseConQueso
@“you're no Jon Skeet” – fancy that. But perhaps he’s me and created a second account to anonymously post second-rate solutions to fight his boredom. ;-)
Konrad Rudolph
+6  A: 

I would start by filtering the abnormal data so you only have regular names. Then something like this should do the trick

$t = "Parisi, Kenneth";
$t =~ s/(.+),\s*(.).*/\l$2\l$1/;
Brian Rasmussen
i ran into a roadblock "Marphy-Smulka, Mara" comes in as "mmarphy-smulka"how do you think i can get rid of the "-" or just use the first part of the last name excluding any non-alphabetical characters
CheeseConQueso
+7  A: 
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
Vinko Vrsalovic
how come I didn't get notified of all the answers? I took a long time and I wondered why nobody had answered yet... heh!
Vinko Vrsalovic
dont know... they came pretty quick.. i only posted this q about 10 minutes ago.... thanks for the input anyway, i think rasmussen's answer is working fine so far
CheeseConQueso
hey vinko... im seeing that last names like "O'neil, Pat" and "Parisi-Caid, Kenneth" come in as pneil and kcaid.... the second one is fine, but the O'neil, Pat would be better to come in as poneil
CheeseConQueso
Here it is modified. If you need to filter out more characters than ' and - you can add them between the [] below the "filter out unneeded charaters" comment
Vinko Vrsalovic
sweet deal... thanks buddy
CheeseConQueso
works! - thanks again
CheeseConQueso
The only thing that bothers me about this is that I posted a question very similar to this on Perl Monks, and would have gotten more help from SO than from Perl Monks for the same question (This was quite a few months ago).
George Stocker
+2  A: 

Here's a one line solution, assuming you store all the names in a file called "names" (one per line) and you will do duplicated name detection somehow later.

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

It looks like your input data is comma-separated. To me, the clearest way to do this would be split into components, and then generate the login names from that:

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";
}
nohat
A: 
 $rowfetch =~ s/['-]//g; #All chars inside the [ ] will be filtered out.
 $rowfetch =~ m/(\w+), ?(.)/;
 $rowfetch = lc($2.$1);

this is how I ended up using Vinko Vrsalovic's solution... its inside a while loop that goes through a sql query result ... thanks again vinko

CheeseConQueso