專欄地址:每週一個 Python 模組
使用 Unix shell 規則查詢與模式匹配的檔名。
儘管 glob
API 不多,但該模組具有很強的功能。當程式需要通過名稱與模式匹配的方式查詢檔案列表時,它很有用。要建立一個檔案列表,這些檔名具有特定的副檔名,字首或中間的任何公共字串,這個時候,使用glob
而不是編寫自定義程式碼來掃描目錄內容。
glob
模式規則與 re
模組使用的正規表示式不同。相反,它們遵循標準的 Unix 路徑擴充套件規則,只有少數特殊字元用於實現兩個不同的萬用字元和字元範圍。模式規則應用於檔名段(在路徑分隔符處停止/
),模式中的路徑可以是相對的或絕對的,Shell 變數名和波浪號(~
)不會展開。
示例資料
本節中的示例假定當前工作目錄中存在以下測試檔案。
dir
dir/file.txt
dir/file1.txt
dir/file2.txt
dir/filea.txt
dir/fileb.txt
dir/file?.txt
dir/file*.txt
dir/file[.txt
dir/subdir
dir/subdir/subfile.txt
複製程式碼
萬用字元
星號(*
)匹配名稱段中的零個或多個字元。例如,dir/*
。
import glob
for name in sorted(glob.glob('dir/*')):
print(name)
# output
# dir/file *.txt
# dir/file.txt
# dir/file1.txt
# dir/file2.txt
# dir/file?.txt
# dir/file[.txt
# dir/filea.txt
# dir/fileb.txt
# dir/subdir
複製程式碼
該模式匹配目錄 dir 中的每個路徑名(檔案或目錄),而不會進一步遞迴到子目錄中。返回的資料未排序,因此這裡的示例對其進行排序以便更直觀地展示結果。
要列出子目錄中的檔案,子目錄必須包含在模式中。
import glob
print('Named explicitly:')
for name in sorted(glob.glob('dir/subdir/*')):
print(' {}'.format(name))
print('Named with wildcard:')
for name in sorted(glob.glob('dir/*/*')):
print(' {}'.format(name))
# output
# Named explicitly:
# dir/subdir/subfile.txt
# Named with wildcard:
# dir/subdir/subfile.txt
複製程式碼
前面顯示的第一種情況明確列出了子目錄名稱,而第二種情況依賴於萬用字元來查詢目錄。
在這種情況下,結果是相同的。如果有另一個子目錄,則萬用字元將匹配兩個子目錄幷包含兩者的檔名。
單字元萬用字元
問號(?
)是另一個萬用字元。它匹配名稱中該位置的任何單個字元。
import glob
for name in sorted(glob.glob('dir/file?.txt')):
print(name)
# output
# dir/file*.txt
# dir/file1.txt
# dir/file2.txt
# dir/file?.txt
# dir/file[.txt
# dir/filea.txt
# dir/fileb.txt
複製程式碼
示例匹配所有以 file
開頭的檔名,具有任何型別的單個字元,然後以 .txt
結束。
字元範圍
使用字元範圍([a-z]
)而不是問號來匹配多個字元之一。此示例在副檔名之前查詢名稱中帶有數字的所有檔案。
import glob
for name in sorted(glob.glob('dir/*[0-9].*')):
print(name)
# output
# dir/file1.txt
# dir/file2.txt
複製程式碼
字元範圍[0-9]
匹配任何單個數字。範圍根據每個字母/數字的字元程式碼排序,短劃線表示連續字元的連續範圍。可以寫入相同的範圍值[0123456789]
。
轉義元字元
有時需要搜尋名稱中包含特殊元字元(glob
用於模式匹配)的檔案。escape()
函式使用特殊字元“轉義”構建合適的模式,因此它們不會被擴充套件或解釋為特殊字元。
import glob
specials = '?*['
for char in specials:
pattern = 'dir/*' + glob.escape(char) + '.txt'
print('Searching for: {!r}'.format(pattern))
for name in sorted(glob.glob(pattern)):
print(name)
print()
# output
# Searching for: 'dir/*[?].txt'
# dir/file?.txt
#
# Searching for: 'dir/*[*].txt'
# dir/file*.txt
#
# Searching for: 'dir/*[[].txt'
# dir/file[.txt
複製程式碼
通過構建包含單個條目的字元範圍來轉義每個特殊字元。
相關文件: