diff --git a/common/str.cpp b/common/str.cpp index 8ed652f8471..24341ddc44b 100644 --- a/common/str.cpp +++ b/common/str.cpp @@ -884,6 +884,7 @@ bool matchString(const char *str, const char *pat, bool ignoreCase, bool pathMod const char *p = nullptr; const char *q = nullptr; + bool escaped = false; for (;;) { if (pathMode && *str == '/') { @@ -893,6 +894,7 @@ bool matchString(const char *str, const char *pat, bool ignoreCase, bool pathMod return false; } + const char curPat = *pat; switch (*pat) { case '*': if (*str) { @@ -912,12 +914,23 @@ bool matchString(const char *str, const char *pat, bool ignoreCase, bool pathMod return true; break; + case '\\': + if (!escaped) { + pat++; + break; + } + // fallthrough + case '#': - if (!isDigit(*str)) - return false; - pat++; - str++; - break; + // treat # as a wildcard for digits unless escaped + if (!escaped) { + if (!isDigit(*str)) + return false; + pat++; + str++; + break; + } + // fallthrough default: if ((!ignoreCase && *pat != *str) || @@ -940,6 +953,8 @@ bool matchString(const char *str, const char *pat, bool ignoreCase, bool pathMod pat++; str++; } + + escaped = !escaped && (curPat == '\\'); } } diff --git a/common/str.h b/common/str.h index 704114b68e5..54044cfac06 100644 --- a/common/str.h +++ b/common/str.h @@ -179,6 +179,7 @@ public: * "*": any character, any amount of times. * "?": any character, only once. * "#": any decimal digit, only once. + * "\#": #, only once. * * Example strings/patterns: * String: monkey.s01 Pattern: monkey.s?? => true diff --git a/test/common/str.h b/test/common/str.h index 783ed53c482..3c69d1792c0 100644 --- a/test/common/str.h +++ b/test/common/str.h @@ -335,6 +335,10 @@ class StringTestSuite : public CxxTest::TestSuite TS_ASSERT(Common::matchString("monkey.s01", "monkey.s##")); TS_ASSERT(!Common::matchString("monkey.s01", "monkey.###")); + TS_ASSERT(Common::matchString("monkey.s0#", "monkey.s0\\#")); + TS_ASSERT(!Common::matchString("monkey.s0#", "monkey.s0#")); + TS_ASSERT(!Common::matchString("monkey.s01", "monkey.s0\\#")); + TS_ASSERT(!Common::String("").matchString("*_")); TS_ASSERT(Common::String("a").matchString("a***")); }