3

What's the best way to escape an arbitrary std::wstring for use inside a regular expression? For example, convert you owe me $ to you owe me \$?

My scenario: I want to use a std::tr1::wregex to search for a whole word. So I want to do something like:

std::wstring RegexEscape(const std::wstring& inp)
{
    return ?????
}

bool ContainsWholeWord(const std::wstring& phrase, const std::wstring& word)
{
    std::tr1::wregex regex(std::wstring(L"\\b") + RegexEscape(word) + L"\\b");
    return std::tr1::regex_match(phrase, regex);
}

2 Answers 2

1

I don't know that it's the cleverest or the most efficient, but I use something like the following:

namespace {
bool
isMeta( char ch )
{
    static bool const meta[UCHAR_MAX] =
    {
        // ...
    };
    return meta[static_cast<unsigned char>( ch )];
}

std::string
sanitizeForRegEx( std::string const& original )
{
    std::string result;
    for ( std::string::const_iterator iter = original.begin();
            iter != original.end();
            ++ iter ) {
        if ( isMeta( *iter ) ) {
            result += '\\';
        result += *iter;
    }
    return result;
}

For wchar_t, I'd modify isMeta to return something like:

return ch >= 0 && ch < 128 && meta[ ch ];

The initialization of meta is a bit of a bore, and the exact values depend on the regular expressions used (or even the options if boost::regex is used).

Sign up to request clarification or add additional context in comments.

Comments

1

Well, that's quite simple! Just use a regular expression to do that!

std::wstring szTmp; // some string with $, (, ...
std::wregex rgx_Meta( LR"(([\^\$\\\.\*\+\?\(\)\[\]\{\}\|]))" );
std::wstring strEscaped( std::regex_replace( szTmp, rgx_Meta, LR"(\$1)" ) );

This will replace all special character like '$' with '\$'.

1 Comment

Good idea, but we should add extra slash to the code as the following. std::wstring szTmp(L"x:\\"); std::wregex rgx_Meta(L"(([\\^\\$\\\\\\.\*\\+\\?\(\)\[\]\\{\\}\\|]))"); std::wstring strEscaped(std::regex_replace(szTmp, rgx_Meta, L"\\$1"));

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.