@@ -20,171 +20,169 @@ String.prototype.ucfirst = function() {
2020 return this . substr ( 0 , 1 ) . toUpperCase ( ) + this . substr ( 1 , this . length - 1 ) . toLowerCase ( ) ;
2121} ;
2222
23- function NameParse ( ) {
24- var me = this ;
23+ function NameParse ( ) { }
2524
2625 // split full names into the following parts:
2726 // - prefix / salutation (Mr., Mrs., etc)
2827 // - given name / first name
2928 // - middle initials
3029 // - surname / last name
3130 // - suffix (II, Phd, Jr, etc)
32- NameParse . prototype . parse = function ( fullastName ) {
33- fullastName = fullastName . trim ( ) ;
34- // split into words
35- var unfilteredNameParts = fullastName . split ( " " ) ;
36- var nameParts = [ ] ;
37- var lastName = "" ;
38- var firstName = "" ;
39- var initials = "" ;
40- var j = 0 ;
41- var i = 0 ;
42- // completely ignore any words in parentheses
43- for ( i = 0 ; i < unfilteredNameParts . length ; i ++ ) {
44- if ( unfilteredNameParts [ i ] . indexOf ( "(" ) == - 1 ) {
45- nameParts [ j ++ ] = unfilteredNameParts [ i ] ;
46- }
31+ NameParse . parse = function ( fullastName ) {
32+ fullastName = fullastName . trim ( ) ;
33+ // split into words
34+ var unfilteredNameParts = fullastName . split ( " " ) ;
35+ var nameParts = [ ] ;
36+ var lastName = "" ;
37+ var firstName = "" ;
38+ var initials = "" ;
39+ var j = 0 ;
40+ var i = 0 ;
41+ // completely ignore any words in parentheses
42+ for ( i = 0 ; i < unfilteredNameParts . length ; i ++ ) {
43+ if ( unfilteredNameParts [ i ] . indexOf ( "(" ) == - 1 ) {
44+ nameParts [ j ++ ] = unfilteredNameParts [ i ] ;
4745 }
48- var numWords = nameParts . length ;
49- // is the first word a title? (Mr. Mrs, etc)
50- var salutation = me . is_salutation ( nameParts [ 0 ] ) ;
51- var suffix = me . is_suffix ( nameParts [ nameParts . length - 1 ] ) ;
52- // set the range for the middle part of the name (trim prefixes & suffixes)
53- var start = ( salutation ) ? 1 : 0 ;
54- var end = ( suffix ) ? numWords - 1 : numWords ;
55-
56- // concat the first name
57- for ( i = start ; i < ( end - 1 ) ; i ++ ) {
58- word = nameParts [ i ] ;
59- // move on to parsing the last name if we find an indicator of a compound last name (Von, Van, etc)
60- // we use i != start to allow for rare cases where an indicator is actually the first name (like "Von Fabella")
61- if ( me . is_compound_lastName ( word ) && i != start ) {
62- break ;
63- }
64- // is it a middle initial or part of their first name?
65- // if we start off with an initial, we'll call it the first name
66- if ( me . is_initial ( word ) ) {
67- // is the initial the first word?
68- if ( i == start ) {
69- // if so, do a look-ahead to see if they go by their middle name
70- // for ex: "R. Jason Smith" => "Jason Smith" & "R." is stored as an initial
71- // but "R. J. Smith" => "R. Smith" and "J." is stored as an initial
72- if ( me . is_initial ( nameParts [ i + 1 ] ) ) {
73- firstName += " " + word . toUpperCase ( ) ;
74- } else {
75- initials += " " + word . toUpperCase ( ) ;
76- }
77- // otherwise, just go ahead and save the initial
46+ }
47+ var numWords = nameParts . length ;
48+ // is the first word a title? (Mr. Mrs, etc)
49+ var salutation = this . is_salutation ( nameParts [ 0 ] ) ;
50+ var suffix = this . is_suffix ( nameParts [ nameParts . length - 1 ] ) ;
51+ // set the range for the middle part of the name (trim prefixes & suffixes)
52+ var start = ( salutation ) ? 1 : 0 ;
53+ var end = ( suffix ) ? numWords - 1 : numWords ;
54+
55+ // concat the first name
56+ for ( i = start ; i < ( end - 1 ) ; i ++ ) {
57+ word = nameParts [ i ] ;
58+ // move on to parsing the last name if we find an indicator of a compound last name (Von, Van, etc)
59+ // we use i != start to allow for rare cases where an indicator is actually the first name (like "Von Fabella")
60+ if ( this . is_compound_lastName ( word ) && i != start ) {
61+ break ;
62+ }
63+ // is it a middle initial or part of their first name?
64+ // if we start off with an initial, we'll call it the first name
65+ if ( this . is_initial ( word ) ) {
66+ // is the initial the first word?
67+ if ( i == start ) {
68+ // if so, do a look-ahead to see if they go by their middle name
69+ // for ex: "R. Jason Smith" => "Jason Smith" & "R." is stored as an initial
70+ // but "R. J. Smith" => "R. Smith" and "J." is stored as an initial
71+ if ( this . is_initial ( nameParts [ i + 1 ] ) ) {
72+ firstName += " " + word . toUpperCase ( ) ;
7873 } else {
79- initials += " " + word . toUpperCase ( ) ;
74+ initials += " " + word . toUpperCase ( ) ;
8075 }
76+ // otherwise, just go ahead and save the initial
8177 } else {
82- firstName += " " + me . fix_case ( word ) ;
83- }
84- }
85-
86- // check that we have more than 1 word in our string
87- if ( ( end - start ) > 1 ) {
88- // concat the last name
89- for ( j = i ; j < end ; j ++ ) {
90- lastName += " " + me . fix_case ( nameParts [ j ] ) ;
78+ initials += " " + word . toUpperCase ( ) ;
9179 }
9280 } else {
93- // otherwise, single word strings are assumed to be first names
94- firstName = me . fix_case ( nameParts [ i ] ) ;
95- }
81+ firstName += " " + this . fix_case ( word ) ;
82+ }
83+ }
9684
97- // return the various parts in an array
98- return {
99- "salutation" : salutation || "" ,
100- "firstName" : firstName . trim ( ) ,
101- "initials" : initials . trim ( ) ,
102- "lastName" : lastName . trim ( ) ,
103- "suffix" : suffix || ""
104- } ;
105- } ;
106-
107- // detect and format standard salutations
108- // I'm only considering english honorifics for now & not words like
109- this . is_salutation = function ( word ) {
110- // ignore periods
111- word = word . replace ( "." , "" ) . toLowerCase ( ) ;
112- // returns normalized values
113- if ( word == "mr" || word == "master" || word == "mister" ) {
114- return "Mr." ;
115- } else if ( word == "mrs" ) {
116- return "Mrs." ;
117- } else if ( word == "miss" || word == "ms" ) {
118- return "Ms." ;
119- } else if ( word == "dr" ) {
120- return "Dr." ;
121- } else if ( word == "rev" ) {
122- return "Rev." ;
123- } else if ( word == "fr" ) {
124- return "Fr." ;
125- } else {
126- return false ;
85+ // check that we have more than 1 word in our string
86+ if ( ( end - start ) > 1 ) {
87+ // concat the last name
88+ for ( j = i ; j < end ; j ++ ) {
89+ lastName += " " + this . fix_case ( nameParts [ j ] ) ;
12790 }
128- } ;
91+ } else {
92+ // otherwise, single word strings are assumed to be first names
93+ firstName = this . fix_case ( nameParts [ i ] ) ;
94+ }
12995
130- // detect and format common suffixes
131- this . is_suffix = function ( word ) {
132- // ignore periods
133- word = word . replace ( / \. / g, "" ) . toLowerCase ( ) ;
134- // these are some common suffixes - what am I missing?
135- var suffixArray = [ 'I' , 'II' , 'III' , 'IV' , 'V' , 'Senior' , 'Junior' , 'Jr' , 'Sr' , 'PhD' , 'APR' , 'RPh' , 'PE' , 'MD' , 'MA' , 'DMD' , 'CME' ] ;
136- for ( var i = 0 ; i < suffixArray . length ; i ++ ) {
137- if ( suffixArray [ i ] . toLowerCase ( ) == word ) {
138- return suffixArray [ i ] ;
139- }
140- }
141- return false ;
142- } ;
143-
144- // detect compound last names like "Von Fange"
145- this . is_compound_lastName = function ( word ) {
146- word = word . toLowerCase ( ) ;
147- // these are some common prefixes that identify a compound last names - what am I missing?
148- var words = [ 'vere' , 'von' , 'van' , 'de' , 'del' , 'della' , 'di' , 'da' , 'pietro' , 'vanden' , 'du' , 'st.' , 'st' , 'la' , 'lo' , 'ter' ] ;
149- return words . in_array ( word ) ;
150- } ;
151-
152- // single letter, possibly followed by a period
153- this . is_initial = function ( word ) {
154- // ignore periods
155- word = word . replace ( "." , "" ) ;
156- return ( word . length == 1 ) ;
96+ // return the various parts in an array
97+ return {
98+ "salutation" : salutation || "" ,
99+ "firstName" : firstName . trim ( ) ,
100+ "initials" : initials . trim ( ) ,
101+ "lastName" : lastName . trim ( ) ,
102+ "suffix" : suffix || ""
157103 } ;
104+ } ;
158105
159- // detect mixed case words like "McDonald"
160- // returns false if the string is all one case
161- // FIXME: No it doesn't. It returns true so long as there is a letter in the string, or if it's empty
162- // FIXME: Also this does not take in to account the first letter being capitalized
163- this . is_camel_case = function ( word ) {
164- var ucReg = / | [ A - Z ] + | s / ;
165- var lcReg = / | [ a - z ] + | s / ;
166- return ( word . match ( ucReg ) != null && word . match ( lcReg ) != null ) ;
167- } ;
168-
169- // ucfirst words split by dashes or periods
170- // ucfirst all upper/lower strings, but leave camelcase words alone
171- this . fix_case = function ( word ) {
172- // uppercase words split by dashes, like "Kimura-Fay"
173- word = me . safe_ucfirst ( "-" , word ) ;
174- // uppercase words split by periods, like "J.P."
175- word = me . safe_ucfirst ( "." , word ) ;
176- return word ;
177- } ;
106+ // detect and format standard salutations
107+ // I'm only considering english honorifics for now & not words like
108+ NameParse . is_salutation = function ( word ) {
109+ // ignore periods
110+ word = word . replace ( "." , "" ) . toLowerCase ( ) ;
111+ // returns normalized values
112+ if ( word == "mr" || word == "master" || word == "mister" ) {
113+ return "Mr." ;
114+ } else if ( word == "mrs" ) {
115+ return "Mrs." ;
116+ } else if ( word == "miss" || word == "ms" ) {
117+ return "Ms." ;
118+ } else if ( word == "dr" ) {
119+ return "Dr." ;
120+ } else if ( word == "rev" ) {
121+ return "Rev." ;
122+ } else if ( word == "fr" ) {
123+ return "Fr." ;
124+ } else {
125+ return false ;
126+ }
127+ } ;
178128
179- // helper this.for fix_case
180- this . safe_ucfirst = function ( seperator , word ) {
181- var words = [ ] ;
182- // uppercase words split by the seperator (ex. dashes or periods)
183- parts = word . split ( seperator ) ;
184- for ( var i = 0 ; i < parts . length ; i ++ ) {
185- var thisWord = parts [ i ] ;
186- words [ i ] = ( me . is_camel_case ( thisWord ) ) ? thisWord : thisWord . ucfirst ( ) ;
129+ // detect and format common suffixes
130+ NameParse . is_suffix = function ( word ) {
131+ // ignore periods
132+ word = word . replace ( / \. / g, "" ) . toLowerCase ( ) ;
133+ // these are some common suffixes - what am I missing?
134+ var suffixArray = [ 'I' , 'II' , 'III' , 'IV' , 'V' , 'Senior' , 'Junior' , 'Jr' , 'Sr' , 'PhD' , 'APR' , 'RPh' , 'PE' , 'MD' , 'MA' , 'DMD' , 'CME' ] ;
135+ for ( var i = 0 ; i < suffixArray . length ; i ++ ) {
136+ if ( suffixArray [ i ] . toLowerCase ( ) == word ) {
137+ return suffixArray [ i ] ;
187138 }
188- return words . join ( seperator ) ;
189- } ;
190- }
139+ }
140+ return false ;
141+ } ;
142+
143+ // detect compound last names like "Von Fange"
144+ NameParse . is_compound_lastName = function ( word ) {
145+ word = word . toLowerCase ( ) ;
146+ // these are some common prefixes that identify a compound last names - what am I missing?
147+ var words = [ 'vere' , 'von' , 'van' , 'de' , 'del' , 'della' , 'di' , 'da' , 'pietro' , 'vanden' , 'du' , 'st.' , 'st' , 'la' , 'lo' , 'ter' ] ;
148+ return words . in_array ( word ) ;
149+ } ;
150+
151+ // single letter, possibly followed by a period
152+ NameParse . is_initial = function ( word ) {
153+ // ignore periods
154+ word = word . replace ( "." , "" ) ;
155+ return ( word . length == 1 ) ;
156+ } ;
157+
158+ // detect mixed case words like "McDonald"
159+ // returns false if the string is all one case
160+ // FIXME: No it doesn't. It returns true so long as there is a letter in the string, or if it's empty
161+ // FIXME: Also this does not take in to account the first letter being capitalized
162+ NameParse . is_camel_case = function ( word ) {
163+ var ucReg = / | [ A - Z ] + | s / ;
164+ var lcReg = / | [ a - z ] + | s / ;
165+ return ( word . match ( ucReg ) != null && word . match ( lcReg ) != null ) ;
166+ } ;
167+
168+ // ucfirst words split by dashes or periods
169+ // ucfirst all upper/lower strings, but leave camelcase words alone
170+ NameParse . fix_case = function ( word ) {
171+ // uppercase words split by dashes, like "Kimura-Fay"
172+ word = this . safe_ucfirst ( "-" , word ) ;
173+ // uppercase words split by periods, like "J.P."
174+ word = this . safe_ucfirst ( "." , word ) ;
175+ return word ;
176+ } ;
177+
178+ // helper this.for fix_case
179+ NameParse . safe_ucfirst = function ( seperator , word ) {
180+ var words = [ ] ;
181+ // uppercase words split by the seperator (ex. dashes or periods)
182+ parts = word . split ( seperator ) ;
183+ for ( var i = 0 ; i < parts . length ; i ++ ) {
184+ var thisWord = parts [ i ] ;
185+ words [ i ] = ( this . is_camel_case ( thisWord ) ) ? thisWord : thisWord . ucfirst ( ) ;
186+ }
187+ return words . join ( seperator ) ;
188+ } ;
0 commit comments