转义用于嵌入std :: regex的String常量

时间:2015-08-27 14:01:48

标签: c++ regex c++11 escaping

C ++ 11有6种不同的正则表达式语法可供使用。就我而言,我正在与使用修改后的ECMAScript正则表达式的组件进行交互。

我需要创建一个正则表达式“匹配以X开头的字符串”,其中X是我的字符串文字。

所以我想要的正则表达式大致为^X.*。除了字符串X可以包含更多正则表达式特殊字符,我希望它们出现。

这意味着我真的想要^ escaped(X) .*

现在,我可以阅读ECMAScript文档,找到所有具有特殊含义的字符,编写一个逃避它们的函数,然后完成。但这似乎不优雅,低效且容易出错 - 特别是如果我想支持当前C ++支持的所有6种正则表达式,更不用说将来了。

标准中有一种简单的方法可以将文字字符串转义为嵌入C ++正则表达式,可能是正则表达式语法的函数,还是我必须自己滚动?

Here是一个使用boost库的类似问题,其中转义列表是硬编码的,然后生成一个反斜杠的正则表达式。我是否因为std

而适应该答案

2 个答案:

答案 0 :(得分:1)

(稍后回答,所以OP可能已经解决了一些问题,但仍然可以)。

初步评论:使用ECMAScript(可能还有其他)语法的正则表达式为^X,此后不需要多余的.*

关于完成此任务的方法:您正在寻求所有正则表达式语法选项的通用解决方案。好吧, YAGNI -You ain't gonna need it。除非您正在编写应该支持所有C ++ regexp语法的通用库,否则请不要尝试自己立即解决整个世界的问题。自从您提出问题以来,就进一步强调了这一事实,因为C ++中已添加了其他正则表达式语法选项...因此,对于C ++ 17,我认为是10个。参见here

因此,我建议您编写可能可以扩展到其他语法选项的内容,但目前仅在需要的语法选项下才有效。例如:

template <std::regex::syntax_option_type SyntaxOption>
std::string escape_for_regex(const std::string_view sv);

或者也许

template <std::regex::syntax_option_type SyntaxOption>
std::string_view
escape_for_regex(
    const std::string_view source, 
    std::string_view destination
);

其中返回的string_view指示您实际使用的目的地数量。一个人可以骑车去掉一些更多的签名(例如,也许使用迭代器吗?范围?)

,您将专门针对std::regex::ECMAScript。此SO问题中提供了实现:

Is there a RegExp.escape function in JavaScript?

答案是没有,但是您可以这样添加(在Javascript中是这样):

RegExp.escape = function(s) {
    return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
};

将其移至C ++,并使用函数签名的第一个选项,即变为:

template <>
std::string escape_for_regex<std::regex::ECMAScript>(const std::string_view sv)
{
    const std::regex to_escape("[-/\\\\^$*+?.()|[\\]{}]");
    const std::string escaped("\\$1");
    const std::string s{sv};
    return std::regex_replace(s, to_escape, escaped);
}

注意:尚未对此进行正确测试。我也不喜欢多余的字符串构造,因此可能regex_replace的另一个变体可能是可用的。

答案 1 :(得分:0)

如果你必须自己编写,你只需要知道两种 BRE和其他人。

这些应该在下面工作。使用 ECMAScript 类型的正则表达式对输入字符串进行操作。

以下正则表达式是使用特殊字符从此处制定的:
What special characters must be escaped in regular expressions?
在回答Legacy RegEx Flavors (BRE/ERE)

两者都使用相同的替代品:"\\\\$1"

对于 BRE 输入:

 # "(\\\\[+?(){}|]|[.^$*\\[\\]\\\\-])"


 (                             # (1 start)
      \\ [+?(){}|]             # not sure this is needed (its not needed)
   |  
      [.^$*\[\]\\-] 
 )                             # (1 end)

对于 ERE ECMAScript 输入:

 # "([.^$*+?()\\[\\]{}\\\\|-])"

 ( [.^$*+?()\[\]{}\\|-] )      # (1)

BRE输入示例

之前 -

+_)(*&^%$#@!asdfasfd hello
+ ? ( ) { } |
\+ \? \( \) \{ \} \|
\\+ \\? \\( \\) \\{ \\} \\|
}{":][';/.,<>? 
here is

之后 -

+_)(\*&\^%\$#@!asdfasfd hello
+ ? ( ) { } |
\\+ \\? \\( \\) \\{ \\} \\|
\\\\+ \\\\? \\\\( \\\\) \\\\{ \\\\} \\\\|
}{":\]\[';/\.,<>? 
here is