将regex_search与std::string一起使用时的无限循环

Infinite loop when using regex_search with std::string

本文关键字:无限循环 一起 string search std regex      更新时间:2023-10-16

为什么下面的代码会导致无限循环?

#include <boost/regex.hpp>
#include <iostream>
#include <string>
int main()
{
  const std::string formula = "LAST_BID_EURUSD$ LAST_ASK_USDJPY$";
  boost::smatch matches;
  boost::regex expr("(LAST_(?:BID|ASK)_.+?\$)");
  while (boost::regex_search(formula, matches, expr))
  {
    std::cout << std::string(matches[1].first, matches[1].second) << std::endl;
  }
}

如果我将迭代器传递给formulabeginend,而不是formula本身,并相应地更新start,则一切都如预期:

#include <boost/regex.hpp>
#include <iostream>
#include <string>
int main()
{
  const std::string formula = "LAST_BID_EURUSD$ LAST_ASK_USDJPY$";
  auto start = formula.begin();
  auto end = formula.end();
  boost::smatch matches;
  boost::regex expr("(LAST_(?:BID|ASK)_.+?\$)");
  while (boost::regex_search(start, end, matches, expr))
  {
    std::cout << std::string(matches[1].first, matches[1].second) << std::endl;
    start = matches[0].second;
  }
}

输出

LAST_BID_EURUSD$
LAST_ASK_USDJPY$

C++11正则表达式也是如此。

它应该如何与std::string对象一起使用?

在第一个片段中,您一遍又一遍地进行相同的调用。

boost::regex_search(formula, matches, expr)

这个调用每次都会得到相同的结果(即成功),这并不奇怪

在第二个片段中,每次循环都要更新start迭代器,因此搜索的"字符串"越来越小,直到最终搜索失败,循环终止。

boost::regex_search(start, end, matches, expr)

需要:类型双向迭代器满足双向迭代机(24.1.4)的要求。

这是boost文档页面中的行。您需要提供Iterators,而不是对象本身。

Boost文档

在c++11文档中

参数

第一个,最后一个-识别目标字符序列的范围

意味着它需要iterators来定义范围。

C++11文档页面

为方便起见,以下是文档页面中给出的片段

#include <string>
#include <map>
#include <boost/regex.hpp>
// purpose: 
// takes the contents of a file in the form of a string 
// and searches for all the C++ class definitions, storing 
// their locations in a map of strings/int's 
typedef std::map<std::string, int, std::less<std::string> > map_type;
boost::regex expression(
   "^(template[[:space:]]*<[^;:{]+>[[:space:]]*)?"
   "(class|struct)[[:space:]]*"
   "(\<\w+\>([[:blank:]]*\([^)]*\))?"
   "[[:space:]]*)*(\<\w*\>)[[:space:]]*"
   "(<[^;:{]+>[[:space:]]*)?(\{|:[^;\{()]*\{)");
void IndexClasses(map_type& m, const std::string& file)
{
   std::string::const_iterator start, end;
   start = file.begin();
   end = file.end();
      boost::match_results<std::string::const_iterator> what;
   boost::match_flag_type flags = boost::match_default;
   while(regex_search(start, end, what, expression, flags))
   {
      // what[0] contains the whole string 
      // what[5] contains the class name. 
      // what[6] contains the template specialisation if any. 
      // add class name and position to map: 
      m[std::string(what[5].first, what[5].second)
            + std::string(what[6].first, what[6].second)]
         = what[5].first - file.begin();
      // update search position: 
      start = what[0].second;
      // update flags: 
      flags |= boost::match_prev_avail;
      flags |= boost::match_not_bob;
   }
}

查看IndexClasses功能的第2行和第3行

因为您没有提供任何Iterators,我认为,您正在运行某种无限循环。