如何转义字符串以在 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 中使用的主要内容,如果未能解决你的问题,请参考以下文章
无法在 C# 中使用 Regex.Unescape 删除转义序列