关于python:.gitignore样式fnmatch()

.gitignore style fnmatch()

用Python拥有.gitignore样式fnmatch()的最简单方法是什么。 看起来stdlib没有提供match()函数,该函数将针对UNIX样式路径正则表达式匹配路径规范。

  • fnmatch()仅匹配纯文件名,没有路径http://docs.python.org/library/fnmatch.html?highlight=fnmatch#fnmatch

  • glob()将执行目录列表,但不提供match()true / false样式函数http://docs.python.org/py3k/library/glob.html?highlight=glob#glob.glob

.gitignore同时具有路径和带有通配符的文件(黑名单)

  • https://github.com/miohtama/Krusovice/blob/master/.gitignore

  • http://linux.die.net/man/5/gitignore


现在有一个名为pathspec的库,它实现了完整的.gitignore规范,包括诸如**/*.py之类的内容; 该文档没有详细描述这些选项,但是说它是git兼容的,并且代码可以处理它们。

1
2
3
4
5
6
7
>>> 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'])

如果要使用.gitignore示例中列出的混合UNIX通配符模式,为什么不只采用每种模式,并在re.search中使用fnmatch.translate

1
2
3
4
5
6
7
8
import fnmatch
import re

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

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

translate将通配符模式转换为re模式

隐藏的UNIX文件:

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