Add wxRegEx::QuoteMeta() helper

Quote all characters special for wxRegEx in the given string: this can
be useful when searching for a literal string using wxRegEx.

Closes https://github.com/wxWidgets/wxWidgets/pull/1489
This commit is contained in:
Tomay
2019-08-24 22:26:50 +01:00
committed by Vadim Zeitlin
parent 363cdc5fdc
commit 050ca4ce3a
4 changed files with 62 additions and 0 deletions

View File

@@ -142,6 +142,8 @@ public:
int ReplaceAll(wxString *text, const wxString& replacement) const
{ return Replace(text, replacement, 0); }
static wxString QuoteMeta(const wxString& str);
// dtor not virtual, don't derive from this class
~wxRegEx();

View File

@@ -250,5 +250,31 @@ public:
Replace the first occurrence.
*/
int ReplaceFirst(wxString* text, const wxString& replacement) const;
/**
Escapes any of the characters having special meaning for wxRegEx.
Currently the following characters are special: \\, ^, $, ., |, ?, *,
+, (, ), [, ], { and }. All occurrences of any of these characters in
the passed string are escaped, i.e. a backslash is inserted before
them, to remove their special meaning.
For example:
@code
wxString quoted = wxRegEx::QuoteMeta("foo.*bar");
assert( quoted == R"(foo\.\*bar)" );
@endcode
This function can be useful when using wxRegEx to search for a literal
string entered by user, for example.
@param str
A string that may contain metacharacters to escape.
@return A string with all metacharacters escaped.
@since 3.1.3
*/
static wxString QuoteMeta(const wxString& str);
};

View File

@@ -690,4 +690,29 @@ int wxRegEx::Replace(wxString *pattern,
return m_impl->Replace(pattern, replacement, maxMatches);
}
wxString wxRegEx::QuoteMeta(const wxString& str)
{
static const wxString s_strMetaChars = wxS("\\^$.|?*+()[]{}");
wxString strEscaped;
// This is the maximal possible length of the resulting string, if every
// character were escaped.
strEscaped.reserve(str.length() * 2);
for ( wxString::const_iterator it = str.begin(); it != str.end(); ++it )
{
if ( s_strMetaChars.find(*it) != wxString::npos )
{
strEscaped += wxS('\\');
}
strEscaped += *it;
}
strEscaped.shrink_to_fit();
return strEscaped;
}
#endif // wxUSE_REGEX

View File

@@ -334,5 +334,14 @@ CPPUNIT_TEST_SUITE_REGISTRATION(wxRegExTestSuite);
// also include in its own registry so that these tests can be run alone
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(wxRegExTestSuite, "wxRegExTestSuite");
TEST_CASE("wxRegEx::QuoteMeta", "[regex][meta]")
{
CHECK( wxRegEx::QuoteMeta("") == "" );
CHECK( wxRegEx::QuoteMeta("a") == "a" );
CHECK( wxRegEx::QuoteMeta("?") == "\\?" );
CHECK( wxRegEx::QuoteMeta("\\") == "\\\\" );
CHECK( wxRegEx::QuoteMeta("\\?!") == "\\\\\\?!" );
CHECK( wxRegEx::QuoteMeta(":foo.*bar") == ":foo\\.\\*bar" );
}
#endif // wxUSE_REGEX