import glob
list = glob.glob(r'*abc*.txt') + glob.glob(r'*123*.txt') + glob.glob(r'*a1b*.txt')
for i in list:
print i
このコードは、名前に「abc」、「123」、または「a1b」が含まれる現在のフォルダー内のファイルを一覧表示するために機能します。
1つのグロブを使用してこの機能を実行するにはどうすればよいですか?ありがとう!
最も簡単な方法は、グロブの結果を自分でフィルタリングすることです。簡単なループ内包表記を使用してそれを行う方法を次に示します。
import glob
res = [f for f in glob.glob("*.txt") if "abc" in f or "123" in f or "a1b" in f]
for f in res:
print f
正規表現を使用し、glob
を使用しないこともできます。
import os
import re
res = [f for f in os.listdir(path) if re.search(r'(abc|123|a1b).*\.txt$', f)]
for f in res:
print f
(ちなみに、list
はPython type ...)であるため、変数にlist
という名前を付けるのは悪い考えです。)
他の回答に基づいて、これを行う準備ができた方法を次に示します。これは最もパフォーマンスが重要ではありませんが、説明どおりに機能します。
def reglob(path, exp, invert=False):
"""glob.glob() style searching which uses regex
:param exp: Regex expression for filename
:param invert: Invert match to non matching files
"""
m = re.compile(exp)
if invert is False:
res = [f for f in os.listdir(path) if m.search(f)]
else:
res = [f for f in os.listdir(path) if not m.search(f)]
res = map(lambda x: "%s/%s" % ( path, x, ), res)
return res
ここで答えがフィルターを使用していないことに驚いています。
import os
import re
def glob_re(pattern, strings):
return filter(re.compile(pattern).match, strings)
filenames = glob_re(r'.*(abc|123|a1b).*\.txt', os.listdir())
これは、リスト、タプル、辞書(すべてのキーが文字列の場合)などを含む文字列を返すイテレータを受け入れます。部分一致をサポートする場合は、.match
を.search
に変更できます。これは明らかにジェネレーターを返すので、結果を繰り返し処理せずに使用したい場合は、結果を自分でリストに変換するか、returnステートメントをlist(...)でラップすることができます。
for filename in glob.iglob(path_to_directory + "*.txt"):
if filename.find("abc") != -1 or filename.find("123") != -1 or filename.find("a1b") != -1:
print filename