【问题标题】:Why does regex_match throw "complexity exception"?为什么 regex_match 会抛出“复杂性异常”?
【发布时间】:2014-03-12 04:36:05
【问题描述】:

我正在尝试测试(使用boost::regex)文件中的一行是否仅包含由空格分隔的数字条目。我遇到了一个我不明白的异常(见下文)。如果有人能解释为什么会抛出它,那就太好了。也许我在这里以定义模式的方式做了一些愚蠢的事情?这是代码:

// regex_test.cpp
#include <string>
#include <iostream>
#include <boost/regex.hpp>
using namespace std;
using namespace boost;

int main(){
  // My basic pattern to test for a single numeric expression
  const string numeric_value_pattern = "(?:-|\\+)?[[:d:]]+\\.?[[:d:]]*";
  // pattern for the full line
  const string numeric_sequence_pattern = "([[:s:]]*"+numeric_value_pattern+"[[:s:]]*)+";

  regex r(numeric_sequence_pattern);
  string line= "1 2 3 4.444444444444";
  bool match = regex_match(line, r);
  cout<<match<<endl;

  //...
}

我编译成功了

g++ -std=c++11 -L/usr/lib64/ -lboost_regex regex_test.cpp  

到目前为止,生成的程序运行良好,match == true 如我所愿。但后来我测试了一个输入行,比如

string line= "1 2 3 4.44444444e-16"; 

当然,我的模式不是为识别4.44444444e-16 格式而构建的,我希望match == false。但是,相反,我收到以下运行时错误:

terminate called after throwing an instance of  
'boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<std::runtime_error> >'  
  what():  The complexity of matching the regular expression exceeded predefined bounds.  
Try refactoring the regular expression to make each choice made by the state machine unambiguous.  
This exception is thrown to prevent "eternal" matches that take an indefinite period time to locate.  

为什么会这样?
注意:我给出的例子是极端的,因为在点之后少放一位就可以了。这意味着

string line= "1 2 3 4.4444444e-16";

正如预期的那样导致match == false。所以,我很困惑。这里发生了什么?

已经谢谢了!


更新:
问题似乎解决了。鉴于alejrb 的提示,我将模式重构为

const string numeric_value_pattern = "(?:-|\\+)?[[:d:]]+(?:\\.[[:d:]]*)?";  

这似乎可以正常工作。不知何故,原始模式 [[:d:]]+\\.?[[:d:]]* 中的孤立可选 \\. 留下了以不同方式匹配长数字序列的许多可能性。
我希望这个模式现在是安全的。但是,如果有人找到一种方法来使用它以新形式进行爆炸,请告诉我!对我来说这是否仍然可能不是那么明显......

【问题讨论】:

    标签: c++ regex boost-regex


    【解决方案1】:

    我会说您的正则表达式可能呈指数回溯。为了保护您免受如果输入不再是完全不可行的循环,正则表达式引擎只是中止尝试。

    经常导致此问题的模式之一是 (x+x+)+ 形式的任何形式 - 当您将第一个模式放入第二个模式时,您会在此处建立。

    http://www.regular-expressions.info/catastrophic.html有很好的讨论

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-04-28
      • 2013-09-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-19
      相关资源
      最近更新 更多