【问题标题】:What is an alternative for lookbehind with C++ RegEx?使用 C++ RegEx 进行后视的替代方法是什么?
【发布时间】:2017-09-16 02:51:09
【问题描述】:

我正在使用以下模式:

(?<=<)(?<!>).*?q.*?(?!<)(?=>)

它使用正负前瞻和后瞻来匹配包含在匹配括号中的文字 q

std::regex 不支持后视。那么有什么好的选择呢?

【问题讨论】:

  • 如果同一行中有多个&lt;...&gt; 子字符串,这是一种非常奇怪的模式。如果你仍然需要这个正则表达式,你可以使用&lt;(.*?q.*?)&gt; 并获取smatch_obj.str(1)。但是,&lt;([^&gt;q]*q[^&gt;]*)&gt; 的性能会更好,也会更精确。
  • boost 支持

标签: regex string c++11 regex-lookarounds


【解决方案1】:

注意(?&lt;=&lt;)(?&lt;!&gt;)等于(?&lt;=&lt;)(因为&lt;需要紧跟在当前位置的左边,所以不能有任何&gt;)并且(?!&lt;)(?=&gt;)等于(?=&gt;)(同样的逻辑在这里也适用,因为&gt; 必须紧邻右侧,不会有任何&lt;)。第一个 .*? 不会匹配可能的最短子字符串,它会直接找到第一个 q 的方式,然后是第一个 &gt; 之前的任何 0+ 字符。因此,即使在支持后视的引擎中,该模式也几乎不适合您。

我宁愿使用&lt;([^&lt;&gt;q]*q[^&lt;&gt;]*)&gt; 正则表达式和一个捕获组,并在表达式的开头/结尾使用&lt;&gt; 符号:

std::regex r("<([^<>q]*q[^<>]*)>");
std::string s = "<adqsdq<><abc>5<abq>6<qaz> <hjfffffffk>";
for(std::sregex_iterator i = std::sregex_iterator(s.begin(), s.end(), r);
                         i != std::sregex_iterator();
                         ++i)
{
    std::cout << (*i).str(1)  << srd::endl;
}

C++ demo

输出:abqqaz

【讨论】:

  • 感谢 Wiktor,您的正则表达式的问题在于它没有考虑另一个括号的存在,因此例如&lt;adqsdq&lt;&gt; 不应该匹配,因为左/右中有一个左括号。我希望这是有道理的
  • 好的,使用&lt;([^&lt;&gt;q]*q[^&lt;&gt;]*)&gt;Your regex did not account for that.
  • 现在检查答案,我已使用与您提供的字符串不匹配的正则表达式对其进行了更新。
  • 也许我应该将此作为另一个问题发布,但是如何仅在 C++ RegEx 中替换捕获的组。
  • 不,您不只替换捕获组,您捕获您需要保留的内容,并且只匹配您需要删除的内容。如果您需要替换捕获组中的特定内容,则需要回调。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-12-01
  • 2011-01-15
  • 2012-01-27
  • 1970-01-01
  • 2020-01-25
相关资源
最近更新 更多