2017-05-30 153 views
2

我有這樣的文件列表:如何過濾帶有特定前綴和後綴(擴展名)的文件名?

file_list = ['file1.zip', 'file1.txt'] 
file_prefix = 'file1' 

我想使用filterre只得到file1.txt以上。我試試這個:

regex = re.compile(file_prefix + '.*(!zip).*') 
result = list(filter(regex.search, file_list)) 
# in the above, result should be populated with just ['file1.txt'] 

但是,正則表達式模式不起作用。有人可以幫我解決這個問題嗎?非常感謝先進!

+1

用途: '(?!(\拉鍊*'re.compile file_prefix +)')' – anubhava

+0

有什麼特別的理由使用正則表達式這樣簡單的模式匹配?這有點過頭了...... – zwer

+0

@zwer你會推薦使用什麼,而不是正則表達式? – user1330974

回答

2

可以使用負前瞻是這樣的:

regex = re.compile(file_prefix + '(?!\.zip)') 

代碼:

>>> file_list = ['file1.zip', 'file1.txt'] 
>>> file_prefix = 'file1' 
>>> regex = re.compile(file_prefix + '(?!\.zip)') 
>>> print list(filter(regex.search, file_list)) 
['file1.txt'] 

(?!\.zip)使得當.zip根本不存在下一個位置斷言真正的負先行。

Read more about look-arounds

+2

謝謝!你能解釋爲什麼我們需要添加''!'而不是'!'嗎? – user1330974

+1

我已經添加了一些解釋和一個很好的文檔鏈接。 – anubhava

+1

這很有用。 –

2

無需正則表達式這個解決方案 - 你不需要把一門大炮來拇指鬥爭。使用Python的本地字符串搜索/檢查:

file_list = ["file1.zip", "file1.txt"] 
file_prefix = "file1" 
file_exclude = "zip" 

result = [e for e in file_list if e.startswith(file_prefix) and not e.endswith(file_exclude)] 
# ['file1.txt'] 

也應該快得多。

如果不想僅搜索邊緣,要過濾出沒有zip後綴file_prefix不管它是字符串中(所以你要匹配some_file1.txt後的條目,甚至a_zip_file1.txt,但不是​​),你可以稍微修改:

file_list = ["file1.zip", "file1.txt", "some_file1.txt", "a_zip_file1.txt", "file1_zip.txt"] 
file_prefix = "file1" 
file_exclude = "zip" 

result = [e for e in file_list if e.find(file_exclude) < e.find(file_prefix)] 
# ['file1.txt', 'some_file1.txt', 'a_zip_file1.txt'] 
+0

感謝您分享替代方法。我不知道'find'(甚至是'starts/endswith')是否在Python後臺場景中使用類似於regex的方法。但我必須同意,不使用正則表達式對於大多數讀者來說更容易理解,並且可能像您說的那樣更具性能。 – user1330974

+1

它不使用正則表達式,它使用純C字符串操作(正則表達式引擎使用的東西,但它首先需要加載整個引擎,編譯模式,創建分支......)底線,你應該使用這項工作的正確工具 - 在很多情況下,正則表達式會讓你的生活更輕鬆(在某些情況下,它的運行速度將比單獨通過Python字符串處理所做的更快),但這不是其中之一。 – zwer

+0

謝謝你的額外解釋! – user1330974

相關問題