2012-09-26 68 views
1

我有一個正則表達式,給定全名,應該記錄名和姓。它應該排除後綴,像「小」:如何從全名中提取名字和姓氏

(.+)\s(.+(?!\sJr\.)) 

但這正則表達式對字符串Larry Farry Barry Jones Jr.應用給人的比賽:

1. Larry Farry Barry Jones 
    2. Jr. 

爲什麼我負前瞻不能忽視「小「解析全名時?我想匹配#2包含「瓊斯」。

+0

它沒有給你期望的原因是因爲第二個'。+'本身就是'「Jr.」',而不是(另一個)''Jr.''。 – sawa

+0

假設名稱是「第一」和「最後」,請格外小心。許多文化不遵循這個順序。如果你(天真地)假設你可以拆分姓名,並打算在通信中使用假設的名字,那麼可能會導致客戶或用戶的冒犯。如果您正在處理Web表單,請爲兩者分別放置一個字段。請參閱http://stackoverflow.com/a/259694/128421和http://www.kalzumeus.com/2010/06/17/falsehoods-programmers-believe-about-names/ –

回答

1

而不是試圖用一個單一的正則表達式,我認爲以下將是一個更易於維護的代碼。

full_name = "Larry Farry Barry Jones Jr." 
name_parts = full_name.split - ["Jr."] 
first_name, last_name = name_parts[0], name_parts[-1] 
1

作爲評論提到它是匹配大部分字符串的第一個.*。在這裏,使用前瞻似乎是正確的,因爲您不想返回該值,也不需要將它包含在進一步的匹配中。

以下將拆分所有單詞但不返回'Jr.'所以你可以採取第一個和最後一個結果。

(\w+\s)+?(?!\sJr\.) 

我推薦Rubular練習Ruby RegExp。

1

原因是你的字符串與你的.+相匹配直到結束,然後執行正則表達式,沒有「Jr.」以下(因爲我們已經在最後)==>完美,我們匹配!

但那是因爲你的模式是錯誤的。更好的方式是這樣的:

\S+(?:\s(?!Jr\.)\S+)* 

看到它here on Regexr

方式:

\S+匹配一系列至少一個非空白字符。

(?:\s(?!Jr\.)\S+)*非捕獲組:匹配一個空白,然後如果它不是「Jr.」,則匹配下一個非空白字符序列。這個完整的組可以重複0次或更多次。