| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | package Lingua::EN::NameParse::Simple; | 
| 2 |  |  |  |  |  |  |  | 
| 3 | 2 |  |  | 2 |  | 58810 | use warnings; | 
|  | 2 |  |  |  |  | 5 |  | 
|  | 2 |  |  |  |  | 71 |  | 
| 4 | 2 |  |  | 2 |  | 12 | use strict; | 
|  | 2 |  |  |  |  | 6 |  | 
|  | 2 |  |  |  |  | 55 |  | 
| 5 | 2 |  |  | 2 |  | 4880 | use DBI; | 
|  | 2 |  |  |  |  | 42778 |  | 
|  | 2 |  |  |  |  | 163 |  | 
| 6 | 2 |  |  | 2 |  | 2608 | use DB_File; | 
|  | 0 |  |  |  |  |  |  | 
|  | 0 |  |  |  |  |  |  | 
| 7 |  |  |  |  |  |  | use Fcntl ':flock'; | 
| 8 |  |  |  |  |  |  | use locale; | 
| 9 |  |  |  |  |  |  |  | 
| 10 |  |  |  |  |  |  | =head1 NAME | 
| 11 |  |  |  |  |  |  |  | 
| 12 |  |  |  |  |  |  | Lingua::EN::NameParse::Simple - Parse an English name into component parts | 
| 13 |  |  |  |  |  |  |  | 
| 14 |  |  |  |  |  |  | =head1 VERSION | 
| 15 |  |  |  |  |  |  |  | 
| 16 |  |  |  |  |  |  | Version 0.14 | 
| 17 |  |  |  |  |  |  |  | 
| 18 |  |  |  |  |  |  | =cut | 
| 19 |  |  |  |  |  |  |  | 
| 20 |  |  |  |  |  |  | our $VERSION = '0.14'; | 
| 21 |  |  |  |  |  |  |  | 
| 22 |  |  |  |  |  |  | =head1 SYNOPSIS | 
| 23 |  |  |  |  |  |  |  | 
| 24 |  |  |  |  |  |  | Invoke this package as follows: | 
| 25 |  |  |  |  |  |  |  | 
| 26 |  |  |  |  |  |  | use Lingua::EN::NameParse::Simple; | 
| 27 |  |  |  |  |  |  | my %name = Lingua::EN::NameParse::Simple::ParseName($fullname); | 
| 28 |  |  |  |  |  |  |  | 
| 29 |  |  |  |  |  |  | # %name will contain available values for these keys: | 
| 30 |  |  |  |  |  |  | # TITLE, FIRST, MIDDLE, LAST, SUFFIX | 
| 31 |  |  |  |  |  |  |  | 
| 32 |  |  |  |  |  |  | # unless the FIRST and LAST keys are populated | 
| 33 |  |  |  |  |  |  | # or if digits are found in a key other than SUFFIX, | 
| 34 |  |  |  |  |  |  | # an ERROR key is returned instead. | 
| 35 |  |  |  |  |  |  |  | 
| 36 |  |  |  |  |  |  | unless( defined( $name{'ERROR'} )){ | 
| 37 |  |  |  |  |  |  | print Dumper( \%name ); | 
| 38 |  |  |  |  |  |  | } | 
| 39 |  |  |  |  |  |  |  | 
| 40 |  |  |  |  |  |  | =head1 FUNCTIONS | 
| 41 |  |  |  |  |  |  |  | 
| 42 |  |  |  |  |  |  | =head2 ParseName | 
| 43 |  |  |  |  |  |  |  | 
| 44 |  |  |  |  |  |  | my %name = Lingua::EN::NameParse::Simple::ParseName($fullname); | 
| 45 |  |  |  |  |  |  |  | 
| 46 |  |  |  |  |  |  | returns values for these keys: | 
| 47 |  |  |  |  |  |  | TITLE, FIRST, MIDDLE, LAST, SUFFIX | 
| 48 |  |  |  |  |  |  |  | 
| 49 |  |  |  |  |  |  | =cut | 
| 50 |  |  |  |  |  |  |  | 
| 51 |  |  |  |  |  |  | sub ParseName { | 
| 52 |  |  |  |  |  |  | my(@returnarray,$namearraysize,$i,$j); | 
| 53 |  |  |  |  |  |  | my(@namearray,$fullname,@validtitle,@validsuffix); | 
| 54 |  |  |  |  |  |  | my($titlematch,%name); | 
| 55 |  |  |  |  |  |  | my($nameelement,$tmp,$lnamematch,$mnamematch); | 
| 56 |  |  |  |  |  |  | my($fnamematch,,$suffixmatch,$tmpelement); | 
| 57 |  |  |  |  |  |  | $fullname=$_[0]; | 
| 58 |  |  |  |  |  |  | @namearray=split(/\s+/,$fullname); | 
| 59 |  |  |  |  |  |  | @validtitle = ('MR', 'MS', 'MRS', 'MISS', 'MISTER', 'DR', 'DOCTOR', 'REV', 'REVEREND', 'PASTOR', 'HONORABLE'); | 
| 60 |  |  |  |  |  |  | @validsuffix = ('SR', 'SENIOR', 'JR', 'JUNIOR', 'II', 'III', 'IV'); | 
| 61 |  |  |  |  |  |  | $namearraysize=@namearray; # Number of items in array | 
| 62 |  |  |  |  |  |  | $i=0; # Keep track of name element | 
| 63 |  |  |  |  |  |  | $titlematch=0; | 
| 64 |  |  |  |  |  |  | $lnamematch=0; | 
| 65 |  |  |  |  |  |  | $mnamematch=0; | 
| 66 |  |  |  |  |  |  | $fnamematch=0; | 
| 67 |  |  |  |  |  |  | $suffixmatch=0; | 
| 68 |  |  |  |  |  |  | NAMEPARSE:foreach(@namearray) { | 
| 69 |  |  |  |  |  |  | $nameelement=$_; | 
| 70 |  |  |  |  |  |  | if(($i+1) == $namearraysize) { | 
| 71 |  |  |  |  |  |  | # Test to see if last element | 
| 72 |  |  |  |  |  |  | # Either Suffix or Last Name | 
| 73 |  |  |  |  |  |  | foreach(@validsuffix) { | 
| 74 |  |  |  |  |  |  | $tmp=uc($nameelement); | 
| 75 |  |  |  |  |  |  | $tmp=~s/\[,.]//g; | 
| 76 |  |  |  |  |  |  | $tmp=~s/\,//g; | 
| 77 |  |  |  |  |  |  | $tmp=~s/\.//g; | 
| 78 |  |  |  |  |  |  | if($tmp eq $_) { | 
| 79 |  |  |  |  |  |  | # Suffix detected | 
| 80 |  |  |  |  |  |  | $returnarray[$i][0]="SUFFIX"; | 
| 81 |  |  |  |  |  |  | $nameelement=~s/\[,.]//g; | 
| 82 |  |  |  |  |  |  | $returnarray[$i][1]=$nameelement; | 
| 83 |  |  |  |  |  |  | $suffixmatch++; | 
| 84 |  |  |  |  |  |  | if($lnamematch == 0 && $returnarray[$i-1][0] eq "MIDDLE") { | 
| 85 |  |  |  |  |  |  | # If no last name has been found then next to last element | 
| 86 |  |  |  |  |  |  | # that is a middle name becomes the last name | 
| 87 |  |  |  |  |  |  | $returnarray[$i-1][0] = "LAST"; | 
| 88 |  |  |  |  |  |  | } | 
| 89 |  |  |  |  |  |  | $i++; | 
| 90 |  |  |  |  |  |  | next NAMEPARSE; | 
| 91 |  |  |  |  |  |  | } | 
| 92 |  |  |  |  |  |  | } | 
| 93 |  |  |  |  |  |  | if($lnamematch == 0) { | 
| 94 |  |  |  |  |  |  | # Since Suffix is not found and lastname not found | 
| 95 |  |  |  |  |  |  | # must be a last name | 
| 96 |  |  |  |  |  |  | $returnarray[$i][0]="LAST"; | 
| 97 |  |  |  |  |  |  | $nameelement=~s/\.//g; | 
| 98 |  |  |  |  |  |  | $nameelement=~s/\,//g; | 
| 99 |  |  |  |  |  |  | $returnarray[$i][1]=$nameelement; | 
| 100 |  |  |  |  |  |  | $lnamematch++; | 
| 101 |  |  |  |  |  |  | $i++; | 
| 102 |  |  |  |  |  |  | next NAMEPARSE; | 
| 103 |  |  |  |  |  |  | } else { | 
| 104 |  |  |  |  |  |  | # Must be a middle name | 
| 105 |  |  |  |  |  |  | $returnarray[$i][0]="MIDDLE"; | 
| 106 |  |  |  |  |  |  | $nameelement=~s/\[,.]//g; | 
| 107 |  |  |  |  |  |  | $returnarray[$i][1]=$nameelement; | 
| 108 |  |  |  |  |  |  | $mnamematch=1; | 
| 109 |  |  |  |  |  |  | $i++; | 
| 110 |  |  |  |  |  |  | next NAMEPARSE; | 
| 111 |  |  |  |  |  |  | } | 
| 112 |  |  |  |  |  |  | } elsif(($i+2) == $namearraysize) { | 
| 113 |  |  |  |  |  |  | # Test to see if second to last element | 
| 114 |  |  |  |  |  |  | # See if element is part of the first 3 | 
| 115 |  |  |  |  |  |  | if($i < 3) { | 
| 116 |  |  |  |  |  |  | # Part of first 3 crucial elements | 
| 117 |  |  |  |  |  |  | if($i == 0) { | 
| 118 |  |  |  |  |  |  | # Two element array, first element | 
| 119 |  |  |  |  |  |  | # Check to see if title | 
| 120 |  |  |  |  |  |  | VALIDTITLE:foreach(@validtitle) { | 
| 121 |  |  |  |  |  |  | # See if there is a title match | 
| 122 |  |  |  |  |  |  | $tmp=uc($nameelement); | 
| 123 |  |  |  |  |  |  | $tmp=~s/\[.,]//g; | 
| 124 |  |  |  |  |  |  | $tmp=~s/\,//g; | 
| 125 |  |  |  |  |  |  | $tmp=~s/\.//g; | 
| 126 |  |  |  |  |  |  | # print "$tmp vs $_ test var\n"; | 
| 127 |  |  |  |  |  |  | if($tmp eq $_) { | 
| 128 |  |  |  |  |  |  | # Match! | 
| 129 |  |  |  |  |  |  | $returnarray[$i][0]="TITLE"; | 
| 130 |  |  |  |  |  |  | $returnarray[$i][1]=$nameelement; | 
| 131 |  |  |  |  |  |  | $titlematch++; | 
| 132 |  |  |  |  |  |  | $i++; | 
| 133 |  |  |  |  |  |  | next NAMEPARSE; | 
| 134 |  |  |  |  |  |  | } | 
| 135 |  |  |  |  |  |  | } | 
| 136 |  |  |  |  |  |  | if(substr($nameelement,length($nameelement)-1,1) eq ",") { | 
| 137 |  |  |  |  |  |  | # Check to see if last name | 
| 138 |  |  |  |  |  |  | $returnarray[$i][0]="LAST"; | 
| 139 |  |  |  |  |  |  | $returnarray[$i][1]=$nameelement; | 
| 140 |  |  |  |  |  |  | $lnamematch++; | 
| 141 |  |  |  |  |  |  | $i++; | 
| 142 |  |  |  |  |  |  | next NAMEPARSE; | 
| 143 |  |  |  |  |  |  | } else { | 
| 144 |  |  |  |  |  |  | # Otherwise, must be a first name | 
| 145 |  |  |  |  |  |  | $returnarray[$i][0]="FIRST"; | 
| 146 |  |  |  |  |  |  | $returnarray[$i][1]=$nameelement; | 
| 147 |  |  |  |  |  |  | $fnamematch++; | 
| 148 |  |  |  |  |  |  | $i++; | 
| 149 |  |  |  |  |  |  | next NAMEPARSE; | 
| 150 |  |  |  |  |  |  | } | 
| 151 |  |  |  |  |  |  | } elsif($i == 1) { | 
| 152 |  |  |  |  |  |  | # Three element array, second element | 
| 153 |  |  |  |  |  |  | if($returnarray[$i-1][0] eq "TITLE" || $returnarray[$i-1][0] eq "LAST") { | 
| 154 |  |  |  |  |  |  | # Must be a first name | 
| 155 |  |  |  |  |  |  | $returnarray[$i][0]="FIRST"; | 
| 156 |  |  |  |  |  |  | $nameelement=~s/\,//g; | 
| 157 |  |  |  |  |  |  | $nameelement=~s/\.//g; | 
| 158 |  |  |  |  |  |  | $returnarray[$i][1]=$nameelement; | 
| 159 |  |  |  |  |  |  | $fnamematch=1; | 
| 160 |  |  |  |  |  |  | $i++; | 
| 161 |  |  |  |  |  |  | next NAMEPARSE; | 
| 162 |  |  |  |  |  |  | } elsif($returnarray[$i-1][0] eq "FIRST") { | 
| 163 |  |  |  |  |  |  | # Must be a middle name | 
| 164 |  |  |  |  |  |  | $returnarray[$i][0]="MIDDLE"; | 
| 165 |  |  |  |  |  |  | $nameelement=~s/\,//g; | 
| 166 |  |  |  |  |  |  | $nameelement=~s/\.//g; | 
| 167 |  |  |  |  |  |  | $returnarray[$i][1]=$nameelement; | 
| 168 |  |  |  |  |  |  | $mnamematch=1; | 
| 169 |  |  |  |  |  |  | $i++; | 
| 170 |  |  |  |  |  |  | next NAMEPARSE; | 
| 171 |  |  |  |  |  |  | } | 
| 172 |  |  |  |  |  |  | } elsif($i == 2) { | 
| 173 |  |  |  |  |  |  | # Four element array, third element | 
| 174 |  |  |  |  |  |  | # Must be a middle or a last name but must set to middle until last element is detected | 
| 175 |  |  |  |  |  |  | $returnarray[$i][0]="MIDDLE"; | 
| 176 |  |  |  |  |  |  | $nameelement=~s/\,//g; | 
| 177 |  |  |  |  |  |  | $nameelement=~s/\.//g; | 
| 178 |  |  |  |  |  |  | $returnarray[$i][1]=$nameelement; | 
| 179 |  |  |  |  |  |  | $mnamematch=1; | 
| 180 |  |  |  |  |  |  | $i++; | 
| 181 |  |  |  |  |  |  | next NAMEPARSE; | 
| 182 |  |  |  |  |  |  | } | 
| 183 |  |  |  |  |  |  | } else { | 
| 184 |  |  |  |  |  |  | # Must be a middle (or last name but won't know that | 
| 185 |  |  |  |  |  |  | # until we check the last element so set to middle name) | 
| 186 |  |  |  |  |  |  | $returnarray[$i][0]="MIDDLE"; | 
| 187 |  |  |  |  |  |  | $nameelement=~s/\,//g; | 
| 188 |  |  |  |  |  |  | $nameelement=~s/\.//g; | 
| 189 |  |  |  |  |  |  | $returnarray[$i][1]=$nameelement; | 
| 190 |  |  |  |  |  |  | $mnamematch=1; | 
| 191 |  |  |  |  |  |  | $i++; | 
| 192 |  |  |  |  |  |  | next NAMEPARSE; | 
| 193 |  |  |  |  |  |  | } | 
| 194 |  |  |  |  |  |  | } elsif($i > 2 && ($i+2) < $namearraysize) { | 
| 195 |  |  |  |  |  |  | # All elements after the 3rd and before 2nd to last | 
| 196 |  |  |  |  |  |  | $returnarray[$i][0]="MIDDLE"; | 
| 197 |  |  |  |  |  |  | $nameelement=~s/\,//g; | 
| 198 |  |  |  |  |  |  | $nameelement=~s/\.//g; | 
| 199 |  |  |  |  |  |  | $returnarray[$i][1]=$nameelement; | 
| 200 |  |  |  |  |  |  | $mnamematch=1; | 
| 201 |  |  |  |  |  |  | $i++; | 
| 202 |  |  |  |  |  |  | next NAMEPARSE; | 
| 203 |  |  |  |  |  |  | } elsif($i == 0) { | 
| 204 |  |  |  |  |  |  | # Test to see if first element | 
| 205 |  |  |  |  |  |  | # Test to see if this is a title | 
| 206 |  |  |  |  |  |  | VALIDTITLE:foreach(@validtitle) { | 
| 207 |  |  |  |  |  |  | # See if there is a title match | 
| 208 |  |  |  |  |  |  | $tmp=uc($nameelement); | 
| 209 |  |  |  |  |  |  | $tmp=~s/\[.,]//g; | 
| 210 |  |  |  |  |  |  | $tmp=~s/\,//g; | 
| 211 |  |  |  |  |  |  | $tmp=~s/\.//g; | 
| 212 |  |  |  |  |  |  | # print "$tmp vs $_ test var\n"; | 
| 213 |  |  |  |  |  |  | if($tmp eq $_) { | 
| 214 |  |  |  |  |  |  | # Match! | 
| 215 |  |  |  |  |  |  | $returnarray[$i][0]="TITLE"; | 
| 216 |  |  |  |  |  |  | $returnarray[$i][1]=$nameelement; | 
| 217 |  |  |  |  |  |  | $titlematch++; | 
| 218 |  |  |  |  |  |  | $i++; | 
| 219 |  |  |  |  |  |  | next NAMEPARSE; | 
| 220 |  |  |  |  |  |  | } | 
| 221 |  |  |  |  |  |  | } | 
| 222 |  |  |  |  |  |  | if(substr($nameelement,length($nameelement)-1,1) eq ",") { | 
| 223 |  |  |  |  |  |  | # Detected a last name | 
| 224 |  |  |  |  |  |  | $returnarray[$i][0]="LAST"; | 
| 225 |  |  |  |  |  |  | $nameelement=~s/\,//g; | 
| 226 |  |  |  |  |  |  | $nameelement=~s/\.//g; | 
| 227 |  |  |  |  |  |  | $returnarray[$i][1]=$nameelement; | 
| 228 |  |  |  |  |  |  | $i++; | 
| 229 |  |  |  |  |  |  | $lnamematch++; | 
| 230 |  |  |  |  |  |  | next NAMEPARSE; | 
| 231 |  |  |  |  |  |  | } else { | 
| 232 |  |  |  |  |  |  | # If all else fails, must be first name | 
| 233 |  |  |  |  |  |  | $returnarray[$i][0]="FIRST"; | 
| 234 |  |  |  |  |  |  | $nameelement=~s/\,//g; | 
| 235 |  |  |  |  |  |  | $nameelement=~s/\.//g; | 
| 236 |  |  |  |  |  |  | $returnarray[$i][1]=$nameelement; | 
| 237 |  |  |  |  |  |  | $i++; | 
| 238 |  |  |  |  |  |  | $fnamematch++; | 
| 239 |  |  |  |  |  |  | next NAMEPARSE; | 
| 240 |  |  |  |  |  |  | } | 
| 241 |  |  |  |  |  |  | } elsif($i == 1) { | 
| 242 |  |  |  |  |  |  | # Test to see if second element | 
| 243 |  |  |  |  |  |  | if($returnarray[$i-1][0] eq "TITLE" || $returnarray[$i-1][0] eq "LAST") { | 
| 244 |  |  |  |  |  |  | # First Name | 
| 245 |  |  |  |  |  |  | $returnarray[$i][0]="FIRST"; | 
| 246 |  |  |  |  |  |  | $nameelement=~s/\,//g; | 
| 247 |  |  |  |  |  |  | $nameelement=~s/\.//g; | 
| 248 |  |  |  |  |  |  | $returnarray[$i][1]=$nameelement; | 
| 249 |  |  |  |  |  |  | $i++; | 
| 250 |  |  |  |  |  |  | $fnamematch++; | 
| 251 |  |  |  |  |  |  | next NAMEPARSE; | 
| 252 |  |  |  |  |  |  | } else { | 
| 253 |  |  |  |  |  |  | # Middle Name | 
| 254 |  |  |  |  |  |  | $returnarray[$i][0]="MIDDLE"; | 
| 255 |  |  |  |  |  |  | $nameelement=~s/\,//g; | 
| 256 |  |  |  |  |  |  | $nameelement=~s/\.//g; | 
| 257 |  |  |  |  |  |  | $returnarray[$i][1]=$nameelement; | 
| 258 |  |  |  |  |  |  | $i++; | 
| 259 |  |  |  |  |  |  | $mnamematch++; | 
| 260 |  |  |  |  |  |  | next NAMEPARSE; | 
| 261 |  |  |  |  |  |  | } | 
| 262 |  |  |  |  |  |  | } elsif($i == 2) { | 
| 263 |  |  |  |  |  |  | # Test to see if third element | 
| 264 |  |  |  |  |  |  | # Must be middle if there since there are more than one elements after this | 
| 265 |  |  |  |  |  |  | # Middle Name | 
| 266 |  |  |  |  |  |  | $returnarray[$i][0]="MIDDLE"; | 
| 267 |  |  |  |  |  |  | $nameelement=~s/\,//g; | 
| 268 |  |  |  |  |  |  | $nameelement=~s/\.//g; | 
| 269 |  |  |  |  |  |  | $returnarray[$i][1]=$nameelement; | 
| 270 |  |  |  |  |  |  | $i++; | 
| 271 |  |  |  |  |  |  | $mnamematch++; | 
| 272 |  |  |  |  |  |  | next NAMEPARSE; | 
| 273 |  |  |  |  |  |  | } | 
| 274 |  |  |  |  |  |  | } | 
| 275 |  |  |  |  |  |  | foreach $j (0...(scalar(@returnarray)-1)) { | 
| 276 |  |  |  |  |  |  | $name{$returnarray[$j][0]} = $returnarray[$j][1]; | 
| 277 |  |  |  |  |  |  | } | 
| 278 |  |  |  |  |  |  | foreach my $key ('TITLE','FIRST','MIDDLE','LAST'){ | 
| 279 |  |  |  |  |  |  | if( defined( $name{$key} ) && $name{$key} =~ m/[0-9]/){ | 
| 280 |  |  |  |  |  |  | $name{'ERROR'} = 'We do not expect to see digits in a person\'s name'; | 
| 281 |  |  |  |  |  |  | } | 
| 282 |  |  |  |  |  |  | } | 
| 283 |  |  |  |  |  |  | unless( defined($name{'LAST'}) && defined($name{'FIRST'}) ){ | 
| 284 |  |  |  |  |  |  | $name{'ERROR'} = 'Does not appear to be a person\'s name conforming to traditional English format'; | 
| 285 |  |  |  |  |  |  | } | 
| 286 |  |  |  |  |  |  | if( defined( $name{'ERROR'} )){ | 
| 287 |  |  |  |  |  |  | foreach my $key ('TITLE','FIRST','MIDDLE','LAST','SUFFIX'){ delete $name{$key}; } | 
| 288 |  |  |  |  |  |  | } | 
| 289 |  |  |  |  |  |  | return (%name); | 
| 290 |  |  |  |  |  |  | } # End ParseName | 
| 291 |  |  |  |  |  |  |  | 
| 292 |  |  |  |  |  |  | =head1 AUTHOR | 
| 293 |  |  |  |  |  |  |  | 
| 294 |  |  |  |  |  |  | Hugh Esco, C<<  >> and James Jones | 
| 295 |  |  |  |  |  |  |  | 
| 296 |  |  |  |  |  |  | =head1 BUGS | 
| 297 |  |  |  |  |  |  |  | 
| 298 |  |  |  |  |  |  | Please report any bugs or feature requests | 
| 299 |  |  |  |  |  |  | to C | 
| 300 |  |  |  |  |  |  | rt.cpan.org>, or through the web interface at | 
| 301 |  |  |  |  |  |  | L. | 
| 302 |  |  |  |  |  |  | I will be notified, and then you'll automatically be notified | 
| 303 |  |  |  |  |  |  | of progress on your bug as I make changes. | 
| 304 |  |  |  |  |  |  |  | 
| 305 |  |  |  |  |  |  | =head1 SUPPORT | 
| 306 |  |  |  |  |  |  |  | 
| 307 |  |  |  |  |  |  | You can find documentation for this module with the perldoc command. | 
| 308 |  |  |  |  |  |  |  | 
| 309 |  |  |  |  |  |  | perldoc Lingua::EN::NameParse::Simple | 
| 310 |  |  |  |  |  |  |  | 
| 311 |  |  |  |  |  |  |  | 
| 312 |  |  |  |  |  |  | You can also look for information at: | 
| 313 |  |  |  |  |  |  |  | 
| 314 |  |  |  |  |  |  | =over 4 | 
| 315 |  |  |  |  |  |  |  | 
| 316 |  |  |  |  |  |  | =item * RT: CPAN's request tracker | 
| 317 |  |  |  |  |  |  |  | 
| 318 |  |  |  |  |  |  | L | 
| 319 |  |  |  |  |  |  |  | 
| 320 |  |  |  |  |  |  | =item * AnnoCPAN: Annotated CPAN documentation | 
| 321 |  |  |  |  |  |  |  | 
| 322 |  |  |  |  |  |  | L | 
| 323 |  |  |  |  |  |  |  | 
| 324 |  |  |  |  |  |  | =item * CPAN Ratings | 
| 325 |  |  |  |  |  |  |  | 
| 326 |  |  |  |  |  |  | L | 
| 327 |  |  |  |  |  |  |  | 
| 328 |  |  |  |  |  |  | =item * Search CPAN | 
| 329 |  |  |  |  |  |  |  | 
| 330 |  |  |  |  |  |  | L | 
| 331 |  |  |  |  |  |  |  | 
| 332 |  |  |  |  |  |  | =back | 
| 333 |  |  |  |  |  |  |  | 
| 334 |  |  |  |  |  |  |  | 
| 335 |  |  |  |  |  |  | =head1 ACKNOWLEDGEMENTS | 
| 336 |  |  |  |  |  |  |  | 
| 337 |  |  |  |  |  |  |  | 
| 338 |  |  |  |  |  |  | =head1 COPYRIGHT & LICENSE | 
| 339 |  |  |  |  |  |  |  | 
| 340 |  |  |  |  |  |  | Copyright (C) 2004-2012 by Hugh Esco, James Jones and the Georgia Green Party | 
| 341 |  |  |  |  |  |  |  | 
| 342 |  |  |  |  |  |  | originally written as: | 
| 343 |  |  |  |  |  |  |  | 
| 344 |  |  |  |  |  |  | parser.pm -- Parses a name into its constituent parts | 
| 345 |  |  |  |  |  |  | Copyright (C) 2004 by Hugh Esco, James Jones and the Georgia Green Party | 
| 346 |  |  |  |  |  |  |  | 
| 347 |  |  |  |  |  |  | Original concept and early buggy version by Esco, original | 
| 348 |  |  |  |  |  |  | working module refactored by James Jones as parser.pm in 2004. | 
| 349 |  |  |  |  |  |  | In 2006 the state Committee of the Georgia Green Party agreed | 
| 350 |  |  |  |  |  |  | to release generally useful portions of its code base under | 
| 351 |  |  |  |  |  |  | the Gnu Public License.  The test suite was added and the | 
| 352 |  |  |  |  |  |  | module renamed and packaged for CPAN distribution by Esco | 
| 353 |  |  |  |  |  |  | doing business as CampaignFoundations.com in 2010.  In early | 
| 354 |  |  |  |  |  |  | 2012 Esco again extended this module to report an ERROR key | 
| 355 |  |  |  |  |  |  | in certain circumstances. | 
| 356 |  |  |  |  |  |  |  | 
| 357 |  |  |  |  |  |  | This program is free software; you can redistribute it and/or | 
| 358 |  |  |  |  |  |  | modify it under the terms of the GNU General Public License | 
| 359 |  |  |  |  |  |  | as published by the Free Software Foundation; version 2 dated | 
| 360 |  |  |  |  |  |  | June, 1991 or at your option any later version. | 
| 361 |  |  |  |  |  |  |  | 
| 362 |  |  |  |  |  |  | This program is distributed in the hope that it will be useful, | 
| 363 |  |  |  |  |  |  | but WITHOUT ANY WARRANTY; without even the implied warranty of | 
| 364 |  |  |  |  |  |  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
| 365 |  |  |  |  |  |  | GNU General Public License for more details. | 
| 366 |  |  |  |  |  |  |  | 
| 367 |  |  |  |  |  |  | A copy of the GNU General Public License is available in the | 
| 368 |  |  |  |  |  |  | source tree; if not, write to the Free Software Foundation, | 
| 369 |  |  |  |  |  |  | Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | 
| 370 |  |  |  |  |  |  |  | 
| 371 |  |  |  |  |  |  | =cut | 
| 372 |  |  |  |  |  |  |  | 
| 373 |  |  |  |  |  |  | 1; # End of Lingua::EN::NameParse::Simple | 
| 374 |  |  |  |  |  |  |  |