.gitignore样式的fnmatch()是什么?

11

如何使用Python实现类似.gitignore的fnmatch()最简单的方法是什么?看起来标准库没有提供一个match()函数,可以将路径规范匹配到UNIX风格的路径正则表达式上。

.gitignore既包括路径也包括带通配符的文件需要列入(黑名单)


为什么正则表达式对你无效? - jdi
我更倾向于只接受有效的答案。 - Mikko Ohtamaa
也许我问的问题太难了? :) - Mikko Ohtamaa
我猜你可以这样看,或者只是抱有不切实际的期望。你的一些问题得到了很好的活动,而有些则没有。你也遭到了一些负评或关闭;真的是五花八门。当人们知道你是那种可以被帮助的人时,这确实会激励他们在这个社区与你的问题互动。如果没有什么能让你满意,那么试图提供答案的意义何在呢? - jdi
1
我不是在寻找娱乐或者声望,我在寻找答案。正确的答案将会被接受,我希望人们在尝试之前就能够做到这一点,这样我就不需要无耻地对错误的答案进行投票了。好的答案=好的声望 :) - Mikko Ohtamaa
显示剩余2条评论
2个回答

25

有一个名为pathspec的库,它实现了完整的.gitignore规范,包括像**/*.py这样的东西;文档描述了如何处理Git模式匹配(您也可以查看代码)。

>>> 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'])

9
如果您想使用在.gitignore示例中列出的混合UNIX通配符模式,为什么不只是取每个模式并使用 fnmatch.translate re.search
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

不幸的是,这在使用如 .*(忽略所有UNIX隐藏文件)这样简单的fnmatch模式时失败了。 - Mikko Ohtamaa
@MikkoOhtamaa:我不确定我理解了。我的更新显示它正确地将路径匹配到了一个隐藏的Unix文件。 - jdi
@MikkoOhtamaa:是的,我放弃了。我不理解这些相关性。祝你好运! - jdi
1
但你的方向非常正确 - bug 更像是 Python fnmatch() 本身的深层问题。我会标记这个问题为已关闭,并将此链接留给后代 https://github.com/miohtama/vvv/tree/master/vvv/bzrlib 作为解决方案。 - Mikko Ohtamaa

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接