2015-04-07 52 views
1

我有它包含一個字符串,看起來像這樣的文件:在「Mr.」之前分割一個字符串或「夫人」

"TextMr. XxxxxMrs. YyyyyMrs. ZzzzzTextWordLady ZzzzzMr. Xxxxx" 

現在,我想將它與Python分裂,使其看起來像這樣:

['Text', 'Mr. Xxxxx', 'Mrs. Yyyyy', 'Mrs. Zzzzz', 'Text', 'Word', 'Lady Zzzzz', 'Mr. Xxxxx'] 

目前我使用的是以下情況:

test2 = re.sub(r"([A-Z])", r" \1", data).split() 

這給了我:

['Text', 'Mr.', 'Xxxxx', 'Mrs.', 'Yyyyy', 'Mrs.', 'Zzzzz', 'Text', 'Word', 'Lady', 'Zzzzz', 'Mr.', 'Xxxxx'] 

我知道這可能非常簡單,並且還閱讀了我可以找到的有關正則表達式和標題的所有主題,但沒有人似乎有同樣的問題。我會很高興如果有人能指出我正確的方向,並告訴我什麼是錯誤的(一次,我花了一個小時盯着一個代碼片段,不僅僅是發現我簡單地忘記了*),因爲我會喜歡理解正則表達式。

+0

模式將是'太太\' – hjpotter92

+0

相關:[在正則表達式可選點(http://stackoverflow.com/questions/26907640/optional-dot-in-regex)也與先生/太太點問題。 – fedorqui

+0

「ZzzzzText」如何拆分? –

回答

2

我建議你創建的所有可能的標題可以由名頭去的列表:

>>> titles = "Mr\. Mrs\. Lady Sir".split() 
['Mr\\.', 'Mrs\\.', 'Lady', 'Sir'] 

然後,您可以使用它們來對任何這些創建的正則表達式標題,然後是空格。

>>> title_opt = "(?:(?:" + "|".join(titles) + "))?" 
'(?:(?:Mr\\.|Mrs\\.|Lady|Sir))?' 

然後使用這些標題後跟一個單詞來查找所有的名稱和單詞。

>>> re.findall(title_opt + "[A-Z][a-z]+", text) 
['Text', 'Mr. Xxxxx', 'Mrs. Yyyyy', 'Mrs. Zzzzz', 'Text', 'Word', 'Lady Zzzzz', 'Mr. Xxxxx'] 

或者,建立在你自己的方法,一旦你擁有的名稱,文字和標題列表,你可以使用一個迭代器加入標題從迭代器next字。

>>> names = ['Text', 'Mr.', 'Xxxxx', 'Mrs.', 'Yyyyy', 'Mrs.', 'Zzzzz', 'Text', 'Word', 'Lady', 'Zzzzz', 'Mr.', 'Xxxxx'] 
>>> titles = set("Mr. Mrs. Lady Sir".split()) 
>>> iterator = iter(names) 
>>> [s if s not in titles else s + " " + next(iterator) for s in iterator] 
['Text', 'Mr. Xxxxx', 'Mrs. Yyyyy', 'Mrs. Zzzzz', 'Text', 'Word', 'Lady Zzzzz', 'Mr. Xxxxx'] 
+0

完美地工作。非常感謝你! – Aerdureth

1
(.+?)(?=Mr\.|Mrs\.|$|(?<!)[A-Z]) 

試試這個。看demo.Grab抓取。

https://regex101.com/r/sJ9gM7/59#python

import re 
p = re.compile(r'(.+?)(?=Mr\.|Mrs\.|$|(?<!)[A-Z])', re.MULTILINE) 
test_str = "TextMr. XxxxxMrs. YyyyyMrs. ZzzzzTextWordLady ZzzzzMr. Xxxxx" 

re.findall(p, test_str) 
+0

謝謝你真是太棒了! – Aerdureth