基本的std :: regex,将查询转换为有效掩码

时间:2019-01-20 13:36:36

标签: c++ regex

我需要使用两个特殊的simbols实现简单的正则表达式搜索-星号(*)为任意数量的字符,问号(?)为任意单个字符。查询中的任何其他符号必须按原样解释。

主要问题是如何将输入掩码转换为有效的std :: regex掩码。 我正在将*翻译为。*和?作为。 (点)。所有其他字符必须按原样转义或解释。这是问题所在-如果我转义了除以下字符以外的任何字符,std :: regex会引发异常:$ ^ [\ |。

如果我转义]符号,则会引发异常。如果不转义]符号,则会引发异常。因此,我根本无法搜索]符号。

我认为,这是我的失败,我做错了什么。但是我不明白我的失败在哪里。

我正在使用VS 2017和C ++ 17选项。

#include <string>
#include <regex>

void translate_mask (std::wstring & mask)
{
    std::wstring basic (L"^");
    for (auto c : mask)
    {
        switch (c)
        {
        case L'*':
            basic += L".*";
            break;
        case L'?':
            basic += L'.';
            break;

        case L'$':
        case L'^':
        case L'[':
        case L'\\':
        case L'|':
        case L'.':
            basic += L'\\' + std::wstring (1, c);
            break;

        case L']':      
            basic += L'.';      // workaround? ']' char cannot be escaped, so interpret it is as any single char

            // uncomment any of these lines and exception will be raisen from std::wregex ctor
            //basic += L'\\' + std::wstring (1, c);
            //basic += c;
            break;


        default:
            basic += c;
        }
    }
    basic += L'$';

    mask = std::move (basic);
}

void load_string (std::wstring & str)
{
    // load string from some database, for example
    str = L"[ hello | world of stack ]";
}

bool find (const std::wstring & str, const std::wstring & mask)
{
    try
    {
        std::wregex r (mask, std::wregex::basic);
        std::wsmatch m;
        return std::regex_search (str, m, r);
    }
    catch (...)
    {
        return false;
    }
}

int main ()
{
    std::wstring mask, str;
    // std::wcin >> mask;
    // example input:
    mask = L"[ hello | world of * ]";
    load_string (str);
    translate_mask (mask);
    bool res = find (str, mask);   // returns true

    return 0;
}

如果我尝试将']'字符转义为'\]',则find函数将引发异常。 如果我根本不转义']',则find函数将引发异常。 请参见case L']':函数中的translate_mask

1 个答案:

答案 0 :(得分:0)

您正在使用basic语法(由于不清楚的原因,因为您似乎在考虑ECMASCript语法)。 In that syntax,管道|并不特殊,不应转义。 ]有点特殊,但仅作为方括号表达式的一部分(当您转义[时就不会有);在它外面,不应逃脱。

有了这些更改,您的示例works

请注意,还有其他特殊字符,例如括号()和括号{}