如何转义字符串以在 Boost Regex 中使用

Posted

技术标签:

【中文标题】如何转义字符串以在 Boost Regex 中使用【英文标题】:How to escape a string for use in Boost Regex 【发布时间】:2009-08-10 03:25:50 【问题描述】:

我只是想了解正则表达式,我正在使用 Boost Regex 库。

我需要使用包含特定 URL 的正则表达式,它会阻塞,因为显然 URL 中有一些字符是为正则表达式保留的,需要转义。

Boost 库中是否有任何函数或方法可以为这种用法转义字符串?我知道在大多数其他正则表达式实现中都有这样的方法,但我在 Boost 中没有看到。

或者,是否有需要转义的所有字符的列表?

【问题讨论】:

【参考方案1】:
. ^ $ | ( ) [ ]   * + ? \

具有讽刺意味的是,您可以使用正则表达式来转义您的 URL,以便将其插入到正则表达式中。

const boost::regex esc("[.^$|()\\[\\]*+?\\\\]");
const std::string rep("\\\\&");
std::string result = regex_replace(url_to_escape, esc, rep,
                                   boost::match_default | boost::format_sed);

(标志boost::format_sed指定使用sed的替换字符串格式。在sed中,转义&将输出与整个表达式匹配的任何内容)

或者如果您对 sed 的替换字符串格式不满意,只需将标志更改为 boost::format_perl,您可以使用熟悉的 $& 来引用整个表达式匹配的任何内容。

const std::string rep("\\\\$&");
std::string result = regex_replace(url_to_escape, esc, rep,
                                   boost::match_default | boost::format_perl);

【讨论】:

我尝试使用正则表达式来做这件事,但我仍然相当无能,并且发生了奇怪的事情:p 我今天订购了几本关于正则表达式的书,所以希望我的无知会很短住过!同时,使用常规字符串替换来转义这些字符可以满足我的迫切需求,谢谢。 我在我的答案中添加了一些代码,我认为应该在任何需要转义的字符之前添加一个反斜杠。我已经有一段时间没有使用 boost 了,所以不能保证。 它很接近,只需在 rep 的末尾添加一个“&”就可以了。谢谢。 顺便说一句,从 C++11 开始,我们也可以使用 std::regex。不幸的是,GCC4.8 有很多正则表达式错误。事实上,即使使用 GCC7,SED 表达式也无法正常工作。这是为 GCC8 修复的:gcc.gnu.org/bugzilla/show_bug.cgi?id=83601【参考方案2】:

使用来自 Dav 的代码(+来自 cmets 的修复),我创建了 ASCII/Unicode 函数regex_escape()

std::wstring regex_escape(const std::wstring& string_to_escape) 
    static const boost::wregex re_boostRegexEscape( _T("[.^$|()\\[\\]*+?\\\\]") );
    const std::wstring rep( _T("\\\\&") );
    std::wstring result = regex_replace(string_to_escape, re_boostRegexEscape, rep, boost::match_default | boost::format_sed);
    return result;

对于 ASCII 版本,使用 std::string/boost::regex 而不是 std::wstring/boost::wregex

【讨论】:

【参考方案3】:

boost::xpressive相同:

const boost::xpressive::sregex re_escape_text = boost::xpressive::sregex::compile("([\\^\\.\\$\\|\\(\\)\\[\\]\\*\\+\\?\\/\\\\])");

std::string regex_escape(std::string text)
    text = boost::xpressive::regex_replace( text, re_escape_text, std::string("\\$1") );
    return text;

【讨论】:

【参考方案4】:

在 C++11 中,您可以使用 原始字符串文字 来避免转义正则表达式字符串:

std::string myRegex = R"(something\.com)";

参见http://en.cppreference.com/w/cpp/language/string_literal,第 (6) 项。

【讨论】:

以上是关于如何转义字符串以在 Boost Regex 中使用的主要内容,如果未能解决你的问题,请参考以下文章

如何转义变量中的特殊字符以在 bash 中提供命令行参数

如何转义字符串中的特定 HTML 标签

无法在 C# 中使用 Regex.Unescape 删除转义序列

在 C++ 中使用 regex/boost 查找 2 个数字之间的数字

javascript 转义字符串以在HTML中使用

Boost Regex 提供空白捕获