2017-04-27 83 views
0

第一次在這裏發佈。按正則表達式分割,並添加匹配詞典

我想1)分析了以下文字:"keyword: some keywords concept :some concepts"

和2)儲存到字典:['keyword']=>'some keywords', ['concept']=>'some concepts'

在每個「冒號」之前可能有0或1個'空間'。以下是我到目前爲止所嘗試的。

sample_text = "keyword: some keywords concept :some concepts" 

p_res = re.compile("(\S+\s?):").split(sample_text) # Task 1 

d_inc = dict([(k, v) for k,v in zip (p_res[::2], p_res[1::2])]) # Task 2 

但是,列表結果p_res是錯誤的,與指數0,從而產生錯誤的字典在空項。我的正則表達式有什麼問題嗎?

+0

如果它爲空,則應該跳過第一個項目。如果在字符串的開始處找到匹配項,則正則表達式分割操作將始終在列表中的初始位置處生成一個空項目。你可以在代碼中加上'如果不是p_res [0]: \t p_res = p_res [1:]'。 –

+0

或者您可以使用['if not p_res [0]: \t p_res.pop(0)'](https://ideone.com/b7A1aA) –

回答

2

使用re.findall來捕獲匹配組中的列表。然後應用dict將元組列表轉換爲字典。

>>> import re 
>>> s = 'keyword: some keywords concept :some concepts' 
>>> dict(re.findall(r'(\S+)\s*:\s*(.*?)\s*(?=\S+\s*:|$)', s)) 
{'concept': 'some concepts', 'keyword': 'some keywords'} 
>>> 

以上正則表達式會捕獲關鍵字,它是在兩個單獨的組中的對應值。

我假設輸入字符串只包含鍵值對,而鍵不包含任何空格字符。

DEMO

+0

刪除空的第一項。你的假設也是正確的。在大多數情況下,鍵是單個詞或有時是連字符。 –

0

通過此線只需更換任務1:

p_res = re.compile("(\S+\s?):").split(sample_text)[1:] # Task 1 

這將始終忽略由re.split返回的(通常是空的)元素。

背景:爲什麼re.split返回空的第一個結果?

應該採取什麼程序做這個輸入:

sample_text = "Hello! keyword: some keywords concept :some concepts" 

在輸入開頭的文字Hello!不適合您的問題(假定的定義是,用鍵輸入開始)。

你想忽略它嗎?如果出現異常,您是否想要引發異常?你想用特殊的鍵將它添加到你的字典嗎?

re.split不想爲您做出決定:它返回出現的任何信息並作出決定。在我們的解決方案中,我們只是忽略第一個鍵出現之前的任何內容

+0

感謝您指出我們的潛在異常。我認爲這將在預處理任務中處理。你的解決方案解決了這個問題,但我不得不接受@Avinash Raj答案,因爲他的正則表達式比我的更強大。 –