2015-10-17 67 views
3

我想從這樣的列表中提取歌曲名稱:'some text here, songs: song1, song2, song3, fro: othenkl'並獲得['song1', 'song2', 'song3']。所以我嘗試做一個正則表達式:正則表達式僅用於匹配某個單詞後面的內容嗎?

result = re.findall('[Ss]ongs?:?.*', 'songs: songname1, songname2,') 
print re.findall('(?:(\w+),)*', result[0]) 

這完全符合:['', '', '', '', '', '', '', 'songname1', '', 'songname2', ''](除空字符串,但NBD

但我想這樣做在同一行,所以我做的。以下:

print re.findall('[Ss]ongs?:?(?:(\w+),)*','songs: songname1, songname2,') 

但我不明白這是爲什麼無法捕捉一樣兩個以上正則表達式:

['', 'name1', 'name2'] 

有沒有辦法在一行中完成此操作?在這裏簡潔會很有用。謝謝。

回答

1

在這種情況下,您不需要使用re.findall,您最好使用re.search查找歌曲序列,然後用逗號分隔結果,。你也不必使用字符類[Ss]相匹配的資本,你可以用忽略大小寫標誌(re.I):

>>> s ='some text here, songs: song1, song2, song3, fro: othenkl' 
>>> re.search(r'(?<=songs:)(.+),', s,flags=re.I).group(1).split(',') 
[' song1', ' song2', ' song3'] 

(?<=songs:)是一個積極的看後面這將讓你的正則表達式引擎匹配的字符串先通過songs:(.+),將匹配songs:之後的最大字符串,後面跟着逗號,即歌曲序列。

也作爲一種更通用的方式,而不是在你的正則表達式的末尾指定逗號,你可以基於這個事實捕捉歌曲名稱,他們之後是這個模式\s\w+:

>>> re.search(r'(?<=songs:)(.+)(?=\s\w+:)', s).group(1).split(',') 
[' song1', ' song2', ' song3', ''] 
+0

所以,我想你仍然有兩步做,即使它是一個班輪。因爲,你仍然需要通過split(',')'將'search'的結果拆分。 – Sother

+0

請注意,如果捕獲組沒有找到任何匹配項,這將失敗:'re.search(...)'將返回'None',對此,上述表達式不再有意義。 – normanius

2

不,你不能在一個模式中使用re模塊。 你可以做的就是這種模式使用regex module代替:

regex.findall(r'(?:\G(?!\A), |\msongs:)(\w++)(?!:)', s) 

哪裏\G是以前的比賽結束後的位置,\A的字符串的開始,\m一個字邊界後跟字字符,++一個佔有量詞。

相關問題