I want to be able to match a pattern in glob
format to a list of strings, rather than to actual files in the filesystem. Is there any way to do this, or convert a glob
pattern easily to a regex?
相关问题
- how to define constructor for Python's new Nam
- streaming md5sum of contents of a large remote tar
- How to get the background from multiple images by
- Evil ctypes hack in python
- Correctly parse PDF paragraphs with Python
I wanted to add support for recursive glob patterns, i.e.
things/**/*.py
and have relative path matching soexample*.py
doesn't match withfolder/example_stuff.py
.Here is my approach:
While
fnmatch.fnmatch
can be used directly to check whether a pattern matches a filename or not, you can also use thefnmatch.translate
method to generate the regex out of the givenfnmatch
pattern:From the documenation:
On Python 3.4+ you can just use
PurePath.match
.On Python 3.3 or earlier (including 2.x), get
pathlib
from PyPI.Note that to get platform-independent results (which will depend on why you're running this) you'd want to explicitly state
PurePosixPath
orPureWindowsPath
.The
glob
module uses thefnmatch
module for individual path elements.That means the path is split into the directory name and the filename, and if the directory name contains meta characters (contains any of the characters
[
,*
or?
) then these are expanded recursively.If you have a list of strings that are simple filenames, then just using the
fnmatch.filter()
function is enough:but if they contain full paths, you need to do more work as the regular expression generated doesn't take path segments into account (wildcards don't exclude the separators nor are they adjusted for cross-platform path matching).
You can construct a simple trie from the paths, then match your pattern against that:
This mouthful can quickly find matches using globs anywhere along the path:
Good artists copy; great artists steal.
I stole ;)
fnmatch.translate
translates globs?
and*
to regex.
and.*
respectively. I tweaked it not to.This one à la
fnmatch.filter
, bothre.match
andre.search
work.Glob patterns and strings found on this page pass test.
never mind, I found it. I want the fnmatch module.