<commit_before><?php



/**
 * Split a full name into its constituent parts
 *   - prefix/salutation (Mr. Mrs. Dr. etc)
 *   - given/first name
 *   - middle name/initial(s)
 *   - surname (last name)
 *   - suffix (II, PhD, Jr. etc)
 *
 * Author: <NAME>
 *
 * Contribution from Clive Verrall www.cliveverrall.com February 2016
 * 
 * // other contributions: 
 * //   - eric willis [list of honorifics](http://notes.ericwillis.com/2009/11/common-name-prefixes-titles-and-honorifics/)
 * //   - `TomThak` for raising issue #16 and providing [wikepedia resource](https://cs.wikipedia.org/wiki/Akademick%C3%BD_titul)
 * //   - `atla5` for closing the issue.
*/
class FullNameParser {



  /**
   * Create the dictionary of terms for use later
   *
   *  - Common honorific prefixes (english)
   *  - Common compound surname identifiers
   *  - Common suffixes (lineage and professional)
   * Note: longer professional titles should appear earlier in the array than shorter titles to reduce the risk of mis-identification e.g. BEng before BE
   * Also note that case and periods are part of the matching for professional titles and therefore need to be correct, there are no case conversions
   */
  protected $dict = array(
    'prefix' => array(
      'Mr.' => array('mr', 'mister', 'master'),
      'Mrs.' => array('mrs', 'missus', 'missis'),
      'Ms.' => array('ms', 'miss'),
      'Dr.' => array('dr'),
      'Rev.' => array("rev", "rev'd", "reverend"),
      'Fr.' => array('fr', 'father'),
      'Sr.' => array('sr', 'sister'),
      'Prof.' => array('prof', 'professor'),
      'Sir' => array('sir'),
      'Hon.' => array('honorable'),
      'Pres.' => array('president'),
      'Gov' => array('governor','governer'),
      'Ofc' => array('officer'),
      'Msgr' => array('monsignor'),
      'Sr.' => array('sister'),
      'Br.' => array('brother'),
      'Supt.' => array('superintendent'),
      'Rep.' => array('representatitve'),
      'Sen.' => array('senator'),
      'Amb.' => array('ambassador'),
      'Treas.' => array('treasurer'),
      'Sec.' => array('secretary'),
      'Pvt.' => array('private'),
      'Cpl.' => array('corporal'),
      'Sgt.' => array('sargent'),
      'Adm.' => array('administrative','administrator','administrater'),
      'Maj.' => array('major'),
      'Capt.' => array('captain'),
      'Cmdr.' => array('commander'),
      'Lt.' => array('lieutenant'),
      'Lt. Col.' => array('lieutenant colonel'),
      'Col.' => array('colonel'),
      'Gen.' => array('general'),
      'Bc.' => array('bachelor', 'baccalaureus'),
      'BcA.' => array('bachelor of arts', 'baccalaureus artis'),
      'ICDr.' => array('doctor of canon law', 'juris cononici doctor'),
      'Ing.' => array('engineer', 'ingenieur'),
      'Ing. sheet.' => array('architect engineer', 'intrudes upon architectus'),
      'JUDr.' => array('juris doctor utriusque', 'doctor rights'),
      'MDDr.' => array('doctor of dental medicine', 'medicinae doctor dentium'),
      'MgA.' => array('master of arts','magister artis'),
      'Mgr.' => array('master'),
      'MD.' => array('doctor of general medicine'),
      'DVM.' => array('doctor of veterinary medine'),
      'PaedDr.' => array('doctor of education'),
      'PharmDr.' => array('doctor of pharmacy'),
      'PhDr.' => array('doctor of philosophy'),
      'PhMr.' => array('master of pharmacy'),
      'RCDr.' => array('doctor of business studies'),
      'RNDr.' => array('doctor of science'),
      'DSc.' => array('doctor of science'),
      'RSDr.' => array('doctor of socio-political sciences'),
      'RTDr.' => array('doctor of technical sciences'),
      'ThDr.' => array('doctor of theology'),
      'Th.D.' => array('doctor of theology'),
      'ThLic.' => array('licentiate of theology'),
      'ThMgr.' => array('master of theology','master of divinity'),
      'Acad.' => array('academian','academic'),
      'ArtD.' => array('doctor of arts'),
      'DiS.' => array('certified specialist'),
      'As.' => array('assistant'),
      'Odb. As.' => array('assistant professor'),
      'Doc.' => array('associate professor'),
      ' ' => array('the')
    ),
    'compound' => array('da','de','del','della','der','di','du','la','pietro','st.','st','ter','van','vanden','vere','von'),
    'suffixes' => array(
      'line' => array('I','II','III','IV','V','1st','2nd','3rd','4th','5th','Senior','Junior','Jr','Sr'),
      'prof' => array('AO', 'B.A.', 'M.Sc', 'BCompt', 'PhD', 'Ph.D.','APR','RPh','PE','MD', 'M.D.', 'MA','DMD','CME', 'BSc', 'Bsc', 'BSc(hons)', 'Ph.D.', 'BEng', 'M.B.A.', 'MBA', 'FAICD', 'CM', 'OBC', 'M.B.', 'ChB', 'FRCP', 'FRSC',
          'FREng', 'Esq', 'MEng', 'MSc', 'J.D.', 'JD', 'BGDipBus', 'Dip', 'Dipl.Phys','M.H.Sc.', 'MPA', 'B.Comm', 'B.Eng', 'B.Acc', 'FSA', 'PGDM', 'FCPA', 'RN', 'R.N.', 'MSN',
          'PCA', 'PCCRM','PCFP','PCGD','PCHR','PCM','PCPS','PCPM','PCSCM','PCSM','PCMM','PCTC','ACA', 'FCA','ACMA', 'FCMA','AAIA', 'FAIA','CCC','MIPA','FIPA','CIA','CFE','CISA','CFAP',
          'QC', 'Q.C.', 'M.Tech', 'CTA', 'C.I.M.A.', 'B.Ec',
          'CFIA','ICCP','CPS','CAP-OM','CAPTA','TNAOAP','AFA','AVA','ASA','CAIA','CBA','CVA','ICVS','CIIA','CMU','PFM','PRM','CFP','CWM','CCP','EA','CCMT','CGAP','CDFM','CFO','CGFM','CGAT','CGFO','CMFO','CPFO','CPFA',
          'BMD','BIET','P.Eng','PE', 'MBBS', 'MB', 'BCh', 'BAO', 'BMBS', 'MBBChir', 'MBChBa','MPhil','LL.D', 'LLD', 'D.Lit','DEA', 'DESS', 'DClinPsy', 'DSc', 'MRes', 'M.Res', 'Psy.D', 'Pharm.D',
          'BA(Admin)', 'BAcc','BACom','BAdmin','BAE','BAEcon','BA(Ed)','BA(FS)','BAgr','BAH','BAI','BAI(Elect)','BAI(Mech)','BALaw','BAO','BAppSc','BArch','BArchSc','BARelSt','BASc','BASoc', 'DDS', 'D.D.S.',
          'BASS','BATheol','BBA','BBLS', 'BBS','BBus','BChem','BCJ','BCL','BCLD(SocSc)','BClinSci','BCom','BCombSt','BCommEdCommDev','BComp','BComSc','BCoun','BD','BDes','BE','BEcon','BEcon&Fin', 'M.P.P.M.', 'MPPM',
          'BEconSci', 'BEd','BEng','BES','BEng(Tech)','BFA','BFin','BFLS','BFST','BH','BHealthSc','BHSc','BHy','BJur','BL','BLE','BLegSc','BLib','BLing','BLitt','BLittCelt','BLS','BMedSc','BMet',
          'BMid', 'BMin','BMS','BMSc','BMSc','BMS','BMus','BMusEd','BMusPerf','BN', 'BNS','BNurs','BOptom','BPA','BPharm', 'BPhil', 'TTC', 'DIP', 'Tchg', 'BEd', 'MEd','ACIB', 'FCIM', 'FCIS', 'FCS', 'Fcs',
          'Bachelor', 'O.C.', 'JP', 'C.Eng', 'C.P.A.', 'B.B.S.', 'MBE', 'GBE', 'KBE', 'DBE', 'CBE', 'OBE', 'MRICS',  'D.P.S.K.', 'D.P.P.J.', 'DPSK', 'DPPJ', 'B.B.A.', 'GBS', 'MIGEM', 'M.I.G.E.M.', 'FCIS',    
          'BPhil(Ed)', 'BPhys','BPhysio','BPl','BRadiog','BSc', 'B.Sc', 'BScAgr','BSc(Dairy)','BSc(DomSc)','BScEc','BScEcon','BSc(Econ)','BSc(Eng)','BScFor','BSc(HealthSc)','BSc(Hort)', 'BBA', 'B.B.A.',
          'BSc(MCRM)', 'BSc(Med)','BSc(Mid)','BSc(Min)','BSc(Psych)', 'BSc(Tech)','BSD', 'BSocSc','BSS','BStSu','BTchg','BTCP','BTech','BTechEd','BTh','BTheol','BTS','EdB','LittB','LLB','MA','MusB','ScBTech', 
          'CEng', 'FCA', 'CFA', 'Cfa', 'C.F.A.', 'LLB', 'LL.B', 'LLM', 'LL.M', 'CA(SA)', 'C.A.', 'CA','CPA',  'Solicitor',  'DMS', 'FIWO', 'CEnv', 'MICE', 'MIWEM', 'B.Com', 'BCom', 'BAcc', 'BA', 'BEc', 'MEc', 'HDip', 'B.Bus.', 'E.S.C.P.' )
    ),
    'vowels' => array('a','e','i','o','u')
  );

  protected $not_nicknames = array( "(hons)");


  /**
   * This is the primary method which calls all other methods
   *
   * @param string $name the full name you wish to parse
   * @return array returns associative array of name parts
   */
  public function parse_name($full_name) {

    # Remove leading/trailing whitespace
    $full_name = trim($full_name);

    // remove any words that don't add value
    // $full_name = str_replace("(Hons)", '', $full_name );
    // $full_name = str_replace("(hons)", '', $full_name );

    # Setup default vars
    extract(array('salutation' => '', 'fname' => '', 'initials' => '', 'lname' => '', 'suffix' => ''));

    # Find all the professional suffixes possible
    $professional_suffix = $this->get_pro_suffix($full_name);

    // The position of the first professional suffix denotes the end of the name and the start of suffixes
    $first_suffix_index = strlen($full_name);
    foreach ($professional_suffix as $key => $psx) {
      $start = strpos($full_name, $psx);
      if( $start === FALSE ) {<commit_msg>Added static method entry point.<commit_after><?php



/**
 * Split a full name into its constituent parts
 *   - prefix/salutation (Mr. Mrs. Dr. etc)
 *   - given/first name
 *   - middle name/initial(s)
 *   - surname (last name)
 *   - suffix (II, PhD, Jr. etc)
 *
 * Author: <NAME>
 *
 * Contribution from Clive Verrall www.cliveverrall.com February 2016
 * 
 * // other contributions: 
 * //   - eric willis [list of honorifics](http://notes.ericwillis.com/2009/11/common-name-prefixes-titles-and-honorifics/)
 * //   - `TomThak` for raising issue #16 and providing [wikepedia resource](https://cs.wikipedia.org/wiki/Akademick%C3%BD_titul)
 * //   - `atla5` for closing the issue.
*/
class FullNameParser {



  /**
   * Create the dictionary of terms for use later
   *
   *  - Common honorific prefixes (english)
   *  - Common compound surname identifiers
   *  - Common suffixes (lineage and professional)
   * Note: longer professional titles should appear earlier in the array than shorter titles to reduce the risk of mis-identification e.g. BEng before BE
   * Also note that case and periods are part of the matching for professional titles and therefore need to be correct, there are no case conversions
   */
  protected $dict = array(
    'prefix' => array(
      'Mr.' => array('mr', 'mister', 'master'),
      'Mrs.' => array('mrs', 'missus', 'missis'),
      'Ms.' => array('ms', 'miss'),
      'Dr.' => array('dr'),
      'Rev.' => array("rev", "rev'd", "reverend"),
      'Fr.' => array('fr', 'father'),
      'Sr.' => array('sr', 'sister'),
      'Prof.' => array('prof', 'professor'),
      'Sir' => array('sir'),
      'Hon.' => array('honorable'),
      'Pres.' => array('president'),
      'Gov' => array('governor','governer'),
      'Ofc' => array('officer'),
      'Msgr' => array('monsignor'),
      'Sr.' => array('sister'),
      'Br.' => array('brother'),
      'Supt.' => array('superintendent'),
      'Rep.' => array('representatitve'),
      'Sen.' => array('senator'),
      'Amb.' => array('ambassador'),
      'Treas.' => array('treasurer'),
      'Sec.' => array('secretary'),
      'Pvt.' => array('private'),
      'Cpl.' => array('corporal'),
      'Sgt.' => array('sargent'),
      'Adm.' => array('administrative','administrator','administrater'),
      'Maj.' => array('major'),
      'Capt.' => array('captain'),
      'Cmdr.' => array('commander'),
      'Lt.' => array('lieutenant'),
      'Lt. Col.' => array('lieutenant colonel'),
      'Col.' => array('colonel'),
      'Gen.' => array('general'),
      'Bc.' => array('bachelor', 'baccalaureus'),
      'BcA.' => array('bachelor of arts', 'baccalaureus artis'),
      'ICDr.' => array('doctor of canon law', 'juris cononici doctor'),
      'Ing.' => array('engineer', 'ingenieur'),
      'Ing. sheet.' => array('architect engineer', 'intrudes upon architectus'),
      'JUDr.' => array('juris doctor utriusque', 'doctor rights'),
      'MDDr.' => array('doctor of dental medicine', 'medicinae doctor dentium'),
      'MgA.' => array('master of arts','magister artis'),
      'Mgr.' => array('master'),
      'MD.' => array('doctor of general medicine'),
      'DVM.' => array('doctor of veterinary medine'),
      'PaedDr.' => array('doctor of education'),
      'PharmDr.' => array('doctor of pharmacy'),
      'PhDr.' => array('doctor of philosophy'),
      'PhMr.' => array('master of pharmacy'),
      'RCDr.' => array('doctor of business studies'),
      'RNDr.' => array('doctor of science'),
      'DSc.' => array('doctor of science'),
      'RSDr.' => array('doctor of socio-political sciences'),
      'RTDr.' => array('doctor of technical sciences'),
      'ThDr.' => array('doctor of theology'),
      'Th.D.' => array('doctor of theology'),
      'ThLic.' => array('licentiate of theology'),
      'ThMgr.' => array('master of theology','master of divinity'),
      'Acad.' => array('academian','academic'),
      'ArtD.' => array('doctor of arts'),
      'DiS.' => array('certified specialist'),
      'As.' => array('assistant'),
      'Odb. As.' => array('assistant professor'),
      'Doc.' => array('associate professor'),
      ' ' => array('the')
    ),
    'compound' => array('da','de','del','della','der','di','du','la','pietro','st.','st','ter','van','vanden','vere','von'),
    'suffixes' => array(
      'line' => array('I','II','III','IV','V','1st','2nd','3rd','4th','5th','Senior','Junior','Jr','Sr'),
      'prof' => array('AO', 'B.A.', 'M.Sc', 'BCompt', 'PhD', 'Ph.D.','APR','RPh','PE','MD', 'M.D.', 'MA','DMD','CME', 'BSc', 'Bsc', 'BSc(hons)', 'Ph.D.', 'BEng', 'M.B.A.', 'MBA', 'FAICD', 'CM', 'OBC', 'M.B.', 'ChB', 'FRCP', 'FRSC',
          'FREng', 'Esq', 'MEng', 'MSc', 'J.D.', 'JD', 'BGDipBus', 'Dip', 'Dipl.Phys','M.H.Sc.', 'MPA', 'B.Comm', 'B.Eng', 'B.Acc', 'FSA', 'PGDM', 'FCPA', 'RN', 'R.N.', 'MSN',
          'PCA', 'PCCRM','PCFP','PCGD','PCHR','PCM','PCPS','PCPM','PCSCM','PCSM','PCMM','PCTC','ACA', 'FCA','ACMA', 'FCMA','AAIA', 'FAIA','CCC','MIPA','FIPA','CIA','CFE','CISA','CFAP',
          'QC', 'Q.C.', 'M.Tech', 'CTA', 'C.I.M.A.', 'B.Ec',
          'CFIA','ICCP','CPS','CAP-OM','CAPTA','TNAOAP','AFA','AVA','ASA','CAIA','CBA','CVA','ICVS','CIIA','CMU','PFM','PRM','CFP','CWM','CCP','EA','CCMT','CGAP','CDFM','CFO','CGFM','CGAT','CGFO','CMFO','CPFO','CPFA',
          'BMD','BIET','P.Eng','PE', 'MBBS', 'MB', 'BCh', 'BAO', 'BMBS', 'MBBChir', 'MBChBa','MPhil','LL.D', 'LLD', 'D.Lit','DEA', 'DESS', 'DClinPsy', 'DSc', 'MRes', 'M.Res', 'Psy.D', 'Pharm.D',
          'BA(Admin)', 'BAcc','BACom','BAdmin','BAE','BAEcon','BA(Ed)','BA(FS)','BAgr','BAH','BAI','BAI(Elect)','BAI(Mech)','BALaw','BAO','BAppSc','BArch','BArchSc','BARelSt','BASc','BASoc', 'DDS', 'D.D.S.',
          'BASS','BATheol','BBA','BBLS', 'BBS','BBus','BChem','BCJ','BCL','BCLD(SocSc)','BClinSci','BCom','BCombSt','BCommEdCommDev','BComp','BComSc','BCoun','BD','BDes','BE','BEcon','BEcon&Fin', 'M.P.P.M.', 'MPPM',
          'BEconSci', 'BEd','BEng','BES','BEng(Tech)','BFA','BFin','BFLS','BFST','BH','BHealthSc','BHSc','BHy','BJur','BL','BLE','BLegSc','BLib','BLing','BLitt','BLittCelt','BLS','BMedSc','BMet',
          'BMid', 'BMin','BMS','BMSc','BMSc','BMS','BMus','BMusEd','BMusPerf','BN', 'BNS','BNurs','BOptom','BPA','BPharm', 'BPhil', 'TTC', 'DIP', 'Tchg', 'BEd', 'MEd','ACIB', 'FCIM', 'FCIS', 'FCS', 'Fcs',
          'Bachelor', 'O.C.', 'JP', 'C.Eng', 'C.P.A.', 'B.B.S.', 'MBE', 'GBE', 'KBE', 'DBE', 'CBE', 'OBE', 'MRICS',  'D.P.S.K.', 'D.P.P.J.', 'DPSK', 'DPPJ', 'B.B.A.', 'GBS', 'MIGEM', 'M.I.G.E.M.', 'FCIS',    
          'BPhil(Ed)', 'BPhys','BPhysio','BPl','BRadiog','BSc', 'B.Sc', 'BScAgr','BSc(Dairy)','BSc(DomSc)','BScEc','BScEcon','BSc(Econ)','BSc(Eng)','BScFor','BSc(HealthSc)','BSc(Hort)', 'BBA', 'B.B.A.',
          'BSc(MCRM)', 'BSc(Med)','BSc(Mid)','BSc(Min)','BSc(Psych)', 'BSc(Tech)','BSD', 'BSocSc','BSS','BStSu','BTchg','BTCP','BTech','BTechEd','BTh','BTheol','BTS','EdB','LittB','LLB','MA','MusB','ScBTech', 
          'CEng', 'FCA', 'CFA', 'Cfa', 'C.F.A.', 'LLB', 'LL.B', 'LLM', 'LL.M', 'CA(SA)', 'C.A.', 'CA','CPA',  'Solicitor',  'DMS', 'FIWO', 'CEnv', 'MICE', 'MIWEM', 'B.Com', 'BCom', 'BAcc', 'BA', 'BEc', 'MEc', 'HDip', 'B.Bus.', 'E.S.C.P.' )
    ),
    'vowels' => array('a','e','i','o','u')
  );

  protected $not_nicknames = array( "(hons)");


  /**
   * Parse Static entry point.
   *
   * @param string $name the full name you wish to parse
   * @return array returns associative array of name parts
   */
  public static function parse($name) {
    $parser = new self();
    return $parser->parse_name($name);
  }


  /**
   * This is the primary method which calls all other methods
   *
   * @param string $name the full name you wish to parse
   * @return array returns associative array of name parts
   */
  public function parse_name($full_name) {

    # Remove leading/trailing whitespace
    $full_name = trim($full_name);

    // remove any words that don't add value
    // $full_name = str_replace("(Hons)", '', $full_name );
    // $full_name = str_replace("(hons)", '', $full_name );

    # Setup default vars
    extract(array('salutation' => '', 'fname' => '', 'initials' => '', 'lname' => '', 'suffix' => ''));

    # Find all the professional suffixes possible
    $professional_suffix = $this->get_pro_suffix($full_name);

    // The position of the first professional suffix denotes the end of the name and the start of suffixes
    $first_suffix_index = strlen($full_name);
    foreach ($professional_suffix as $key => $psx) {
      $start = strpos($full_name, $psx);
      if( $start === FALSE ) {
{'fraction_non_alphanumeric': 0.2668289208120622, 'fraction_numerical': 0.0022557283628160986, 'mean_word_length': 3.828604184580109, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 160, 'https://': 2, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '282472', 'n_tokens_mistral': 6480, 'n_tokens_neox': 6219, 'n_words': 1245}