xdev.patterns module

An encapsulation of regex and glob (and maybe other) patterns.

class xdev.patterns.PatternBase[source]

Bases: object

match(text)[source]
search(text)[source]
sub(repl, text)[source]
xdev.patterns.our_extended_regex_compile()[source]

Adds suppport for vim-like < and > syntax to represent b

class xdev.patterns.Pattern(pattern, backend)[source]

Bases: PatternBase, NiceRepr

Provides a common API to several common pattern matching syntaxes.

A general patterns class, which can be strict, regex, or glob.

Parameters:
  • pattern (str | object) – The pattern text or a precompiled backend pattern object

  • backend (str) – Code indicating what backend the pattern text should be interpereted with. Current modes are: strict, regex, and glob.

Notes

The glob backend uses the fnmatch module [fnmatch_docs]. The regex backend uses the Python re module. The strict backend uses the “==” string equality testing.

References

Example

>>> repat = Pattern.coerce('foo.*', 'regex')
>>> assert repat.match('foobar')
>>> assert not repat.match('barfoo')
>>> globpat = Pattern.coerce('foo*', 'glob')
>>> assert globpat.match('foobar')
>>> assert not globpat.match('barfoo')
>>> globpat = Pattern.coerce('[foo|bar]', 'glob')
>>> globpat.match('foo')
>>> repat = Pattern.coerce('foo.*', 'regex')
>>> match = repat.search('baz-biz-foobar')
>>> match = repat.match('baz-biz-foobar')
to_regex()[source]

Returns an equivalent pattern with the regular expression backend

Example

>>> globpat = Pattern.coerce('foo*', 'glob')
>>> strictpat = Pattern.coerce('foo*', 'strict')
>>> repat1 = strictpat.to_regex()
>>> repat2 = globpat.to_regex()
>>> print(f'repat1={repat1}')
>>> print(f'repat2={repat2}')
classmethod from_regex(data, flags=0, multiline=False, dotall=False, ignorecase=False)[source]
classmethod from_glob(data)[source]
classmethod coerce_backend(data, hint='glob')[source]
match(text)[source]
search(text)[source]
sub(repl, text, count=-1)[source]
Parameters:
  • repl (str) – text to insert in place of pattern

  • text (str) – text to be searched and modified

  • count (int) – if non-negative, the maximum number of replacements that will be made.

classmethod coerce(data, hint='glob')[source]

Example

>>> pat = Pattern.coerce('foo*', 'glob')
>>> pat2 = Pattern.coerce(pat, 'regex')
>>> print('pat = {}'.format(ub.repr2(pat, nl=1)))
>>> print('pat2 = {}'.format(ub.repr2(pat2, nl=1)))

Pattern.coerce([‘a’, ‘b’, ‘c’])

paths(cwd=None, recursive=False)[source]

Find paths in the filesystem that match this pattern

Yields:

ub.Path

class xdev.patterns.MultiPattern(patterns, predicate)[source]

Bases: PatternBase, NiceRepr

Example

>>> dpath = ub.Path.appdir('xdev/tests/multipattern_paths').ensuredir().delete().ensuredir()
>>> (dpath / 'file0.txt').touch()
>>> (dpath / 'data0.dat').touch()
>>> (dpath / 'other0.txt').touch()
>>> ((dpath / 'dir1').ensuredir() / 'file1.txt').touch()
>>> ((dpath / 'dir2').ensuredir() / 'file2.txt').touch()
>>> ((dpath / 'dir2').ensuredir() / 'file3.txt').touch()
>>> ((dpath / 'dir1').ensuredir() / 'data.dat').touch()
>>> ((dpath / 'dir2').ensuredir() / 'data.dat').touch()
>>> ((dpath / 'dir2').ensuredir() / 'data.dat').touch()
>>> pat = MultiPattern.coerce(['*.txt'], 'glob')
>>> print(list(pat.paths(cwd=dpath)))
>>> pat = MultiPattern.coerce(['*0*', '**/*.txt'], 'glob')
>>> print(list(pat.paths(cwd=dpath, recursive=1)))
>>> pat = MultiPattern.coerce(['*.txt', '**/*.txt', '**/*.dat'], 'glob')
>>> print(list(pat.paths(cwd=dpath)))
match(text)[source]
paths(cwd=None, recursive=False)[source]
_squeeze()[source]
classmethod coerce(data, hint='glob', predicate='any')[source]

Example

>>> pat = MultiPattern.coerce('foo*', 'glob')
>>> pat2 = MultiPattern.coerce(pat, 'regex')
>>> pat3 = MultiPattern.coerce([pat, pat], 'regex')
>>> print('pat = {}'.format(ub.repr2(pat, nl=1)))
>>> print('pat2 = {}'.format(ub.repr2(pat2, nl=1)))
>>> print('pat3 = {!r}'.format(pat3))

Pattern.coerce([‘a’, ‘b’, ‘c’])