Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Splitting Names 1

Status
Not open for further replies.

V00D00

Technical User
Jul 11, 2005
78
US
Splitting Names

I need help generating code that will take the following examples and return separate elements.

“John Q Smith”
“John Smith”

I need to have an element for each first middle and last name. The problem I run in to is if the name does not contain a middle initial.

Code:
my @name_parts = split (/\s+\/,$dncprep[0],3);

This code I am using will return the last name to element 1 if there is no middle initial. Any help, I am going loopy...
 
This will never work perfect unless store the name in three fields. But what you can do is use split() without the last argument (,3) which tells split how many times to split the string up.

my @name_parts = split (/\s+\/,$dncprep[0]);

If @name_parts as two scalars you could assume a first and last name only, if three scalars, first, middle and last.
 
How would I go about testing @name_parts for the number of scalars, and then put the data in the right place?

Code:
#!/usr/bin/perl -w
use strict;
use diagnostics;

my ($sec,$min,$hour,$mday,$mon,$year,$wday,$isdst)= localtime;
$year += 1900;
$mon += 1;

print "\nEnter Lead List File Name: ";
chomp (my $sourcefile = <STDIN>);

open(IN, "$sourcefile.txt") or die "Failed to open $sourcefile";
open(OUT, ">$mon$mday$year"."_dncpdate.txt") or die "Failed to write to $mon$mday$year"."_dncupdate.txt";

while (<IN>) {
        my @dncprep = split /\|/, $_;
        my @name_parts = split (/\s+/,$dncprep[0],3);
        my $phonenumber = $dncprep[5].$dncprep[6];
        my @dncflop = ($name_parts[0],$name_parts[2],$dncprep[1],$dncprep[2],$dncprep[3],$dncprep[4],$phonenumber,$dncprep[8],$dncprep[7]);
        my $outfile = join "\t", @dncflop;
        print OUT "$outfile\n" ;
        }
close (IN) or die "Can't close source: $!";
close (OUT) or die "Can't close file: $!";

I am trying to split them out to put in seperate fields of a new array. I am invisioning some kind of test that looks at the array and counts elements, but thats about the end of my expertise. It seems my little perl book does not cover this. :)
 
Here's one way to go about it:
Code:
my @name = ('John Q Smith', 'John Smith');
foreach (@name) {
    my @name_parts = split;
    if (@name_parts == 2) { push @name_parts, "", splice(@name_parts,1,1); }
    print join('|', @name_parts), "\n";
}
 
or something like:

Code:
if (scalar @name_parts == 2) {
  do something
}
elsif (scalar @name_parts == 3) {
  do something else
}
else {
  print 'AHHH!!! The name is eiter too short or too long! I can't win!';
}

you can also assign the value of @name_parts to a scalar to get the number of elements in the array:

$number = @name_parts;

$number will equal however many scalars are in the array. Or you can check it specifically like I showed above:

if (scalar @name_parts == 2)

or perl will know what to do without the "scalar" operator like in rharsh's code:

if (@name_parts == 2)

I just put it in to make it clear what is going on.

 
Code:
while (<IN>) {
        my @dncprep = split /\|/, $_;
        my @name_parts = split (/\s+/,$dncprep[0],3);
        if (scalar @name_parts == 2) {
        $name_parts[2]=$name_parts[1];
        }
        my $phonenumber = $dncprep[5].$dncprep[6];
        my @dncflop = ($name_parts[0],$name_parts[2],$dncprep[1],$dncprep[2],$dncprep[3],$dncprep[4],$phonenumber,$dncprep[8],$dncprep[7]);
        my $outfile = join "\t", @dncflop;
        print OUT "$outfile\n" ;
        }

Works perfect. Thank you very much.
 
do we know will never have:
John Q Public III
or
Jane Smith Jr.

??
 
I don't know about you guys, but if the middle name was blank, I would have forced a middle name with something really wierd like "555abc" and then gone with the original code.

When the time came to read the data, the "555abc" could be replaced with "".

Very amateurish, but a heck of a lot simpler.

Just a thought.
 
I would have been tempted to do the whole thing with one simple regex:
Code:
my @name = /^(\S+)\s+(?:(.*)\s+)?(\S+)$/;
Then @name will always have three elements: forname, middlenames (or undef) and surname.
You might wish to set any undef to '' to avoid warnings:
Code:
$name[1] = '' unless(defined $name[1]);
The whole issue of handling salutations is very complex. Far more complex than initially appears.
If you need to handle "John J Doe MD" then you need separate code to deal with optional prefixes (Mr, Dr etc) and suffixes (M.D., PhD, etc).


Trojan.
 
Fortunately my data set already has a field for Title or optional prefixes and suffixes. Thank you all very much for your help, as small and useless as these small scripts seem, them do actually save me days of work.

Voodoo
 
Code:
[b]#!/usr/bin/perl[/b]

name = ('John Q Smith', 'John Smith');

foreach (@name) {
  my @name_parts = split;
  $name_parts[2] = $name_parts[1] and $name_parts[1] = '' if @name_parts == 2;
  print "Forename: $name_parts[0] - Surname: $name_parts[2]\n";
}


Kind Regards
Duncan
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top