2015-02-25 6 views
8

तो मेरे प्रमुख दर्द बिंदुओं में से एक नाम समझ है और घरेलू नाम & खिताब मिलकर है।क्या मैं जटिल मानव नामों का विश्लेषण करने के लिए पाइथन 'री' का उपयोग कर सकता हूं?

John Jeffries 
John Jeffries, M.D. 
John Jeffries, MD 
John Jeffries and Jim Smith 
John and Jim Jeffries 
John Jeffries & Jennifer Wilkes-Smith, DDS, MD 
John Jeffries, CPA & Jennifer Wilkes-Smith, DDS, MD 
John Jeffries, C.P.A & Jennifer Wilkes-Smith, DDS, MD 
John Jeffries, C.P.A., MD & Jennifer Wilkes-Smith, DDS, MD 
John Jeffries M.D. and Jennifer Holmes CPA 
John Jeffries M.D. & Jennifer Holmes CPA 

: मैं एक बहुत बड़े पैमाने पर regex मैं एक साथ आज सुबह कि मैं शायद पर गर्व नहीं होना चाहिए डाल (लेकिन बीमार रास्ते की एक किस्म में वैसे भी कर रहा हूँ) के साथ एक 80% समाधान है कि निम्न उदाहरण सही ढंग से मेल खाता है

(?P<first_name>\S*\s*)?(?!and\s|&\s)(?P<last_name>[\w-]*\s*)(?P<titles1>,?\s*(?!and\s|&\s)[\w\.]*,*\s*(?!and\s|&\s)[\w\.]*)?(?P<connector>\sand\s|\s*&*\s*)?(?!and\s|&\s)(?P<first_name2>\S*\s*)(?P<last_name2>[\w-]*\s*)?(?P<titles2>,?\s*[\w\.]*,*\s*[\w\.]*)? 

(WTF है ना?)

सुविधा के लिए: http://www.pyregex.com/

तो, उदाहरण के लिए: रेगुलर एक्सप्रेशन मिलान इस तरह दिखता है

'John Jeffries, C.P.A., MD & Jennifer Wilkes-Smith, DDS, MD' 

एक समूह dict की तरह लग रहा है कि में regex परिणाम:

connector: & 
first_name: John 
first_name2: Jennifer 
last_name: Jeffries 
last_name2: Wilkes-Smith 
titles1: , C.P.A., MD 
titles2: , DDS, MD 

मैं अंतिम चरण है कि कर दिया गया है मुझे ट्रिपिंग, संभव मध्यम नाम समझने के साथ मदद की जरूरत है।

उदाहरणों में शामिल हैं:

'John Jimmy Jeffries, C.P.A., MD & Jennifer Wilkes-Smith, DDS, MD' 
'John Jeffries, C.P.A., MD & Jennifer Jenny Wilkes-Smith, DDS, MD' 

यह संभव है और वहाँ मशीन सीखने के बिना यह करने के लिए एक बेहतर तरीका है? हो सकता है कि मैं nameparser का उपयोग कर सकूं (रेगेक्स खरगोश छेद नीचे जाने के बाद खोजा गया) इसके बजाय यह निर्धारित करने के लिए कि क्या कई नाम हैं या नहीं? उपरोक्त मैचों में 99.9% मामले हैं इसलिए मुझे लगता है कि यह खत्म होने लायक है।

TLDR: मैं समझ नहीं अगर मैं अग्रदर्शी किसी प्रकार का उपयोग करें या यह सुनिश्चित करें कि संभव मध्य नाम केवल तभी इसके बाद एक अंतिम नाम है से मेल खाता बनाने के लिए lookbehind कर सकते हैं।

नोट: मुझे श्रीमती सुश्री आदि जैसे शीर्षकों का विश्लेषण करने की आवश्यकता नहीं है, लेकिन मुझे लगता है कि मध्य नामों के समान ही जोड़ा जा सकता है।

समाधान नोट्स: सबसे पहले, रिचर्ड की सलाह का पालन करें और ऐसा नहीं करते हैं। दूसरा, यदि आवश्यक हो तो अधिक मजबूत समाधान के लिए एनएलटीके की जांच करें या nameparser पर योगदान/योगदान दें।

+14

पायथन की [प्राकृतिक भाषा टूलकिट (एनएलटीके)] (http://www.nltk.org/) * इस कार्य के लिए * अधिक * बेहतर अनुकूल है। इसे देखें: http://timmcnamara.co.nz/post/2650550090/extracting-names-with-6-lines-of-python-code –

+1

@CurtisMattoon ओह। यह अच्छा लग रहा है। मैं अभी कुछ अधिकार प्राप्त करने के लिए इस रेगेक्स पर हैकिंग कर रहा था "अभी सही" लेकिन एनएलटीके एक लंबे दीर्घकालिक समाधान (और शायद अल्पकालिक) की तरह दिखता है। मैं एक जूनियर पायथन देव हूं इसलिए मुझे वहां के सभी समाधानों के बारे में पता नहीं है। – mzniko

+3

भले ही आपके कार्य के लिए बेहतर टूल हो, फिर भी आप अपने वर्तमान रेगेक्स को अधिक पठनीय बनाने के लिए 're.VERBOSE' ध्वज का उपयोग कर सकते हैं। https://docs.python.org/3/library/re.html#re.VERBOSE –

उत्तर

8

इस तरह के नियमित अभिव्यक्ति डार्क वन का काम हैं।

कौन, बाद में आपका कोड देख रहा है, यह समझने में सक्षम होगा कि क्या हो रहा है? क्या तुम भी हो

आप सभी संभावित किनारे के मामलों का परीक्षण कैसे करेंगे?

आपने नियमित अभिव्यक्ति का उपयोग करने के लिए क्यों चुना है? यदि आप जिस उपकरण का उपयोग कर रहे हैं, उसके साथ काम करना मुश्किल है, तो यह सुझाव देता है कि शायद एक और उपकरण बेहतर होगा।

इस प्रयास करें:

import re 

examples = [ 
    "John Jeffries", 
    "John Jeffries, M.D.", 
    "John Jeffries, MD", 
    "John Jeffries and Jim Smith", 
    "John and Jim Jeffries", 
    "John Jeffries & Jennifer Wilkes-Smith, DDS, MD", 
    "John Jeffries, CPA & Jennifer Wilkes-Smith, DDS, MD", 
    "John Jeffries, C.P.A & Jennifer Wilkes-Smith, DDS, MD", 
    "John Jeffries, C.P.A., MD & Jennifer Wilkes-Smith, DDS, MD", 
    "John Jeffries M.D. and Jennifer Holmes CPA", 
    "John Jeffries M.D. & Jennifer Holmes CPA", 
    'John Jimmy Jeffries, C.P.A., MD & Jennifer Wilkes-Smith, DDS, MD', 
    'John Jeffries, C.P.A., MD & Jennifer Jenny Wilkes-Smith, DDS, MD' 
] 

def IsTitle(inp): 
    return re.match('^([A-Z]\.?)+$',inp.strip()) 

def ParseName(name): 
    #Titles are separated from each other and from names with "," 
    #We don't need these, so we remove them 
    name = name.replace(',',' ') 
    #Split name and titles on spaces, combining adjacent spaces 
    name = name.split() 
    #Build an output object 
    ret_name = {"first":None, "middle":None, "last":None, "titles":[]} 
    #First string is always a first name 
    ret_name['first'] = name[0] 
    if len(name)>2: #John Johnson Smith/PhD 
    if IsTitle(name[2]): #John Smith PhD 
     ret_name['last'] = name[1] 
     ret_name['titles'] = name[2:] 
    else:    #John Johnson Smith, PhD, MD 
     ret_name['middle'] = name[1] 
     ret_name['last'] = name[2] 
     ret_name['titles'] = name[3:] 
    elif len(name) == 2: #John Johnson 
    ret_name['last'] = name[1] 
    return ret_name 

def CombineNames(inp): 
    if not inp[0]['last']: 
    inp[0]['last'] = inp[1]['last'] 

def ParseString(inp): 
    inp = inp.replace("&","and") #Names are combined with "&" or "and" 
    inp = re.split("\s+and\s+",inp) #Split names apart 
    inp = map(ParseName,inp) 
    CombineNames(inp) 
    return inp 

for e in examples: 
    print e 
    print ParseString(e) 

आउटपुट:

John Jeffries 
[{'middle': None, 'titles': [], 'last': 'Jeffries', 'first': 'John'}] 
John Jeffries, M.D. 
[{'middle': None, 'titles': ['M.D.'], 'last': 'Jeffries', 'first': 'John'}] 
John Jeffries, MD 
[{'middle': None, 'titles': ['MD'], 'last': 'Jeffries', 'first': 'John'}] 
John Jeffries and Jim Smith 
[{'middle': None, 'titles': [], 'last': 'Jeffries', 'first': 'John'}, {'middle': None, 'titles': [], 'last': 'Smith', 'first': 'Jim'}] 
John and Jim Jeffries 
[{'middle': None, 'titles': [], 'last': 'Jeffries', 'first': 'John'}, {'middle': None, 'titles': [], 'last': 'Jeffries', 'first': 'Jim'}] 
John Jeffries & Jennifer Wilkes-Smith, DDS, MD 
[{'middle': None, 'titles': [], 'last': 'Jeffries', 'first': 'John'}, {'middle': None, 'titles': ['DDS', 'MD'], 'last': 'Wilkes-Smith', 'first': 'Jennifer'}] 
John Jeffries, CPA & Jennifer Wilkes-Smith, DDS, MD 
[{'middle': None, 'titles': ['CPA'], 'last': 'Jeffries', 'first': 'John'}, {'middle': None, 'titles': ['DDS', 'MD'], 'last': 'Wilkes-Smith', 'first': 'Jennifer'}] 
John Jeffries, C.P.A & Jennifer Wilkes-Smith, DDS, MD 
[{'middle': None, 'titles': ['C.P.A'], 'last': 'Jeffries', 'first': 'John'}, {'middle': None, 'titles': ['DDS', 'MD'], 'last': 'Wilkes-Smith', 'first': 'Jennifer'}] 
John Jeffries, C.P.A., MD & Jennifer Wilkes-Smith, DDS, MD 
[{'middle': None, 'titles': ['C.P.A.', 'MD'], 'last': 'Jeffries', 'first': 'John'}, {'middle': None, 'titles': ['DDS', 'MD'], 'last': 'Wilkes-Smith', 'first': 'Jennifer'}] 
John Jeffries M.D. and Jennifer Holmes CPA 
[{'middle': None, 'titles': ['M.D.'], 'last': 'Jeffries', 'first': 'John'}, {'middle': None, 'titles': ['CPA'], 'last': 'Holmes', 'first': 'Jennifer'}] 
John Jeffries M.D. & Jennifer Holmes CPA 
[{'middle': None, 'titles': ['M.D.'], 'last': 'Jeffries', 'first': 'John'}, {'middle': None, 'titles': ['CPA'], 'last': 'Holmes', 'first': 'Jennifer'}] 
John Jimmy Jeffries, C.P.A., MD & Jennifer Wilkes-Smith, DDS, MD 
[{'middle': 'Jimmy', 'titles': ['C.P.A.', 'MD'], 'last': 'Jeffries', 'first': 'John'}, {'middle': None, 'titles': ['DDS', 'MD'], 'last': 'Wilkes-Smith', 'first': 'Jennifer'}] 
John Jeffries, C.P.A., MD & Jennifer Jenny Wilkes-Smith, DDS, MD 
[{'middle': None, 'titles': ['C.P.A.', 'MD'], 'last': 'Jeffries', 'first': 'John'}, {'middle': 'Jenny', 'titles': ['DDS', 'MD'], 'last': 'Wilkes-Smith', 'first': 'Jennifer'}] 

यह कम से कम पंद्रह मिनट का समय लगा और प्रत्येक चरण में, तर्क स्पष्ट है और कार्यक्रम टुकड़ों में डिबग जा सकता है। जबकि एक-लाइनर प्यारे हैं, स्पष्टता और टेस्टेबिलिटी को प्राथमिकता लेनी चाहिए।

+1

मैं अंधेरे जादू के उपयोग को पश्चाताप करता हूं! मुझे आशा है कि इससे दूसरों को इससे बचने में मदद मिलेगी। मैं इसे समाधान के रूप में स्वीकार करूंगा और एनएलटीके और नेमपार्सर lib को लोगों को इंगित करने वाला एक नोट जोड़ूंगा। – mzniko

संबंधित मुद्दे

 संबंधित मुद्दे