From d33b853f668306c85f94fd459e83fdd0bf538fb5 Mon Sep 17 00:00:00 2001 From: Thomas Waldmann Date: Mon, 3 Jul 2017 01:14:53 +0200 Subject: [PATCH] shellpattern: add match_end arg match_end=r"\Z" is the default, same behaviour as before (create a full match up to the string end from the globbing pattern). match_end=otherregex can be flexibly used to match anything else after the regex generated from the globbing pattern. --- src/borg/shellpattern.py | 7 +++++-- src/borg/testsuite/shellpattern.py | 11 +++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/borg/shellpattern.py b/src/borg/shellpattern.py index b8d958343..7c3d76b21 100644 --- a/src/borg/shellpattern.py +++ b/src/borg/shellpattern.py @@ -2,7 +2,7 @@ import os import re -def translate(pat): +def translate(pat, match_end=r"\Z"): """Translate a shell-style pattern to a regular expression. The pattern may include ``**`` ( stands for the platform-specific path separator; "/" on POSIX systems) for @@ -10,6 +10,9 @@ def translate(pat): any path separator. Wrap meta-characters in brackets for a literal match (i.e. "[?]" to match the literal character "?"). + Using match_end=regex one can give a regular expression that is used to match after the regex that is generated from + the pattern. The default is to match the end of the string. + This function is derived from the "fnmatch" module distributed with the Python standard library. Copyright (C) 2001-2017 Python Software Foundation. All rights reserved. @@ -59,4 +62,4 @@ def translate(pat): else: res += re.escape(c) - return res + r"\Z(?ms)" + return res + match_end + "(?ms)" diff --git a/src/borg/testsuite/shellpattern.py b/src/borg/testsuite/shellpattern.py index fae8c75d1..5ca5af400 100644 --- a/src/borg/testsuite/shellpattern.py +++ b/src/borg/testsuite/shellpattern.py @@ -111,3 +111,14 @@ def test_match(path, patterns): def test_mismatch(path, patterns): for p in patterns: assert not check(path, p) + + +def test_match_end(): + regex = shellpattern.translate("*-home") # default is match_end == string end + assert re.match(regex, '2017-07-03-home') + assert not re.match(regex, '2017-07-03-home.checkpoint') + + match_end = r'(%s)?\Z' % r'\.checkpoint(\.\d+)?' # with/without checkpoint ending + regex = shellpattern.translate("*-home", match_end=match_end) + assert re.match(regex, '2017-07-03-home') + assert re.match(regex, '2017-07-03-home.checkpoint')