2013-07-03 6 views
6

Ho un sacco di nomi umani. Sono tutti nomi "occidentali" e ho solo bisogno di convenzioni/abbreviazioni americane (ad es., Invece di Sr. per señor). Sfortunatamente, le persone a cui sto inviando le cose non hanno inserito i loro nomi, quindi non posso chiedere loro come vorrebbero essere chiamati. Conosco il sesso di ogni persona e il suo nome completo, ma non ho veramente analizzato le cose in modo più specifico.Human Name parsing

Alcuni esempi:

  1. John Smith
  2. John Smith, Jr.
  3. John Smith Jr.
  4. John Smith XIV
  5. Dr. John Smith, Ph.D.

mi piacerebbe essere in grado di analizzare le parti di ogni nome:

name = Name.new("John Smith Jr.") 
name.first_name # <= John 
name.greeting # <= Mr. Smith 

Se io sono in cerca di "saluto" (probabilmente non il migliore termine), quello che voglio è qui , per 1-4, "Mr. Smith". Per il 5, vorrei il dottor Smith ma mi accontenterei di Mr. Smith.

Una gemma rubino per questo sarebbe l'ideale. Sono stato ispirato a chiedere qualcosa di strano a Chronic, una gemma di Ruby che gestisce il tempo in modo notevolmente umano, lasciandomi correttamente dire "martedì scorso" e averlo trovato con qualcosa di sensato. "Qualche algoritmo sarebbe sufficiente per colpire di più dei casi d'angolo.

sto cercando di affrontare alcuni dei problemi presentati in falsehoods programmers believe about names

risposta

6

Dal momento che si è limitato a nomi di stile occidentale, penso che alcune regole ti porterà la maggior parte del tragitto:

  1. Se appare una virgola, elimina il quello più a sinistra e tutto dopo.
  2. Continuare a rimuovere le parole dall'inizio mentre, dopo la conversione in minuscolo e la rimozione di eventuali punti fermi, fanno parte del set { mr mrs miss ms rev dr prof } e più si può pensare. Utilizzando una tabella del titolo "punteggi" (ad esempio [mr=1, mrs=1, rev=2, dr=3, prof=4] - ordinali come desideri), registra il titolo con il punteggio più alto che è stato eliminato.
  3. Continuare a rimuovere le parole dalla fine mentre appartengono al set { jr phd } o sono numeri romani di valore circa 50 o meno (/[XVI]+/ è probabilmente una regex abbastanza buona).
  4. Se uno o più titoli con punteggi diversi da zero sono stati eliminati nel passaggio 2, utilizzare quello con il punteggio più alto. Altrimenti, usa "Mr." o "Signora" secondo il genere fornito.
  5. Come cognome, utilizzare l'ultima parola.

Non sarà mai possibile garantire che un nome come "John Baxter Smith" sia analizzato correttamente, dal momento che non tutti i cognomi a doppia canna usano trattini. "Baxter Smith" è il cognome? O è "Baxter" un secondo nome? Penso che sia sicuro presumere che i nomi medi siano relativamente più comuni dei cognomi a doppia canna, ma non unenumerati, il che significa che è meglio impostare di default l'ultima parola come cognome. Potresti anche voler compilare un elenco di comuni cognomi a doppia canna e controllare contro questo, comunque.

+0

Questo mi dà un ottimo punto di partenza per scrivere la mia libreria su DWIW. Risposta accettata – Hut8

2

sguardo sulla lufthansa pagina. chiedono loro quale tipo di 'title' se volessero uso. non ho mai visto meglio

Non consiglio l'uso di gem o qualsiasi cosa in questo caso perché inglese/spagnolo/francese/.... ci sono differenze sul genere, quindi, se provi disco da solo, non puoi avere successo.

Spero che aiutano a

+1

Questa è sicuramente la risposta giusta se si sta ripartendo da zero, ma potrebbe essere che il sistema è già esistito da qualche tempo. –

+0

Sì, sarebbe bello se potessi chiedere a queste persone qualcosa. Purtroppo devo fare una stima migliore. Nota: la mia domanda riguarda anche la distinzione tra John Smith XIV => Mr. Smith, piuttosto che Mr. XIV. Come ho detto nella domanda, conosco già il genere separatamente. – Hut8

1

humanparser

analizzare una stringa nome umano in saluto, il nome, il nome, il cognome, il suffisso.

Installare

npm install humanparser 

Uso

var human = require('humanparser'); 

var fullName = 'Mr. William R. Jenkins, III' 
    , attrs = human.parseName(fullName); 

console.log(attrs); 

//produces the following output 

{ saluation: 'Mr.', 
    firstName: 'William', 
    suffix: 'III', 
    lastName: 'Jenkins', 
    middleName: 'R.', 
    fullName: 'Mr. William R. Jenkins, III' } 
1

Hai provato la gemma rubino Namae?

Dovrebbe occuparsi bene della maggior parte dei nomi occidentali e viene fornito con un paio di opzioni di configurazione per scenari difficili (più cognomi, virgola utilizzata sia per separare i nomi in un elenco che per le parti dei nomi). Detto questo, è un parser deterministico (usando questo grammar) e ci sono alcuni casi che non coprirà.

Ecco il tuo esempio:

require('namae') 

Namae.parse 'John Smith and John Smith, Jr. and John Smith Jr and John Smith XIV' 
#=> [ 
    #<Name family="Smith" given="John">, 
    #<Name family="Smith" given="John" suffix="Jr.">, 
    #<Name family="Smith" given="John" suffix="Jr">, 
    #<Name family="Smith" given="John" suffix="XIV"> 
] 

Si lotta con il titolo del medico, ma questo è qualcosa che potremmo essere in grado di risolvere.

2

C'è un parser basato Perl a disposizione per fare questo tipo di estrazione http://search.cpan.org/~kimryan/Lingua-EN-NameParse/

Ho eseguito attraverso i vostri esempi ottenere le seguenti results.It gestisce solo suffissi ordinali fino a 12 (XII) e anche non riconosce il . in Ph.D quindi ho dovuto modificare questo nei dati di input

JOHN SMITH        John        Smith      
JOHN SMITH, JR.       John        Smith    Jr  
JOHN SMITH JR.       John        Smith    Jr  
JOHN SMITH XII       John        Smith    XII  
DR. JOHN SMITH, PHD    Dr.  John        Smith    Phd