2012-04-06 18 views
7

Pythonで.gitignoreスタイルのfnmatch()を使用する最も簡単な方法は何でしょうか。 stdlibは、UNIXスタイルのパス正規表現に対してパス指定と一致するmatch()関数を提供していないようです。.gitignore style fnmatch()

.gitignoreには、ワイルドカードを含むパスとファイルの両方がリストされます(黒色)。

+0

なぜ正規表現は機能しませんか? – jdi

+0

私は有効な回答のみを受け入れることを好む。 –

+0

私はあまりにも難しい質問をするかもしれませんか? :) –

答えて

6

あなたの.gitignore例に記載されている混合UNIXのワイルドカードパターンを使用したい場合は、その理由だけで各パターンを取り、re.searchfnmatch.translateを使わないのでしょうか?

import fnmatch 
import re 

s = '/path/eggs/foo/bar' 
pattern = "eggs/*" 

re.search(fnmatch.translate(pattern), s) 
# <_sre.SRE_Match object at 0x10049e988> 

translate

は再パターンに

隠しUNIXファイルワイルドカードパターンを回す:

s = '/path/to/hidden/.file' 
isHiddenFile = re.search(fnmatch.translate('.*'), s) 
if not isHiddenFile: 
    # do something with it 
+0

残念なことに、これは、*(すべてのUNIX隠しファイルを無視する)のような単純なfnmatchパターンで失敗します。 –

+0

@MikkoOhtamaa:私は私がフォローしているかわかりません。私の更新は、それが隠されたunixファイルへのパスに適切に一致することを示しています。 – jdi

+0

ここで詳しく説明します:https://bugs.launchpad.net/bzr/+bug/57637 –

12

**/*.pyのようなものを含む完全な.gitignore仕様を実装pathspecと呼ばれるライブラリが今あります。 documentationにはオプションの詳細は記載されていませんが、gitと互換性があり、codeがそのオプションを処理しています。

>>> import pathspec 
>>> spec_src = '**/*.pyc' 
>>> spec = pathspec.PathSpec.from_lines(pathspec.patterns.GitWildMatchPattern,, spec_src.splitlines()) 
>>> set(spec.match_files({"test.py", "test.pyc", "deeper/file.pyc", "even/deeper/file.pyc"})) 
set(['test.pyc', 'even/deeper/file.pyc', 'deeper/file.pyc']) 
>>> set(spec.match_tree("pathspec/")) 
set(['__init__.pyc', 'gitignore.pyc', 'util.pyc', 'pattern.pyc', 'tests/__init__.pyc', 'tests/test_gitignore.pyc', 'compat.pyc', 'pathspec.pyc'])