[Python] 解決 glob.glob() 遇到檔名中有 [ 的問題
Python 的 glob.glob() 函式真是出乎我的意料之外,有不少的隱藏秘笈…
上一次是遇到 不會傳回 Linux 上的隱藏檔 的問題,
今天又遇到了一個怪異狀況,
有個目錄名叫 test[1],目錄下有好幾個檔案,
但是用下列的程式卻傳回了空的 list:
glob.glob("test[1]/*")
百思不得其解,後來看了 python manual,
原來 glob() 會把 *?[] 視為特殊字元…
*? 很容易理解,[] 的話則是代表要符合中括號中的任一字元,
因此上面的程式事實上只會符合到 test1/*,自然是沒有東西了…
瞄了一下 python 2.6 中關於 glob() 的原始碼,
為了解決上述的問題 (加上之前隱藏檔的問題),
決定複製原本的 glob() 函式,修改成我需要的版本,也就是:
1. 要列出隱藏檔
2. 要把 [ 當作普通字元,不要作特殊的 regular expression 用途
下面的 list_matched_filenames() 和 ilist_matched_filenames() 就分別對應到原本的 glob() 和 iglob(),
有興趣的人可以拿來跟 python 2.6 中的 glob() 比較看看囉~~
def list_matched_filenames(pathname, treat_left_bracket_as_normal_char=True): """ This function comes from python 2.6 glob.glob(). We modify it to allow hidden files and treat "[" as normal character. """ return list(ilist_matched_filenames(pathname, treat_left_bracket_as_normal_char)) def ilist_matched_filenames(pathname, treat_left_bracket_as_normal_char=True): """ This function comes from python 2.6 glob.iglob(). We modify it to allow hidden files and treat "[" as normal character. """ def _glob1(dirname, pattern): """ This function comes from python 2.6 glob.glob1(). We modify it to allow hidden files and treat "[" as normal character. """ if not dirname: dirname = os.curdir if isinstance(pattern, unicode) and not isinstance(dirname, unicode): dirname = unicode(dirname, sys.getfilesystemencoding() or sys.getdefaultencoding()) try: names = os.listdir(dirname) except os.error: return [] import fnmatch return fnmatch.filter(names, pattern if not treat_left_bracket_as_normal_char else pattern.replace("[", "[[]")) import glob if not glob.has_magic(pathname): if os.path.lexists(pathname): yield pathname return dirname, basename = os.path.split(pathname) if not dirname: for name in _glob1(os.curdir, basename): yield name return if glob.has_magic(dirname): dirs = ilist_matched_filenames(dirname, treat_left_bracket_as_normal_char) else: dirs = [dirname] if glob.has_magic(basename): glob_in_dir = _glob1 else: glob_in_dir = glob.glob0 for dirname in dirs: for name in glob_in_dir(dirname, basename): yield os.path.join(dirname, name)
(本頁面已被瀏覽過 1,000 次)