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

时间:2015-12-01 09:47:15

标签: c++ regex c++11 boost boost-regex

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

#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;
  }
}

如果我将迭代器传递给begin的{​​{1}}和end而不是formula本身,并相应地更新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;
  }
}

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

它应该如何与LAST_BID_EURUSD$ LAST_ASK_USDJPY$ 个对象一起使用?

2 个答案:

答案 0 :(得分:3)

在第一个代码段中,您反复拨打同一个电话。

boost::regex_search(formula, matches, expr)

每次调用时,这个调用都会给出相同的结果(即成功),这并不奇怪。

在第二个片段中,每次循环都会更新start迭代器,因此您搜索的“字符串”会逐渐变小,直到最终搜索失败,循环终止

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

答案 1 :(得分:-1)

  

要求:类型BidirectionalIterator符合双向迭代器(24.1.4)的要求。

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

Boost Documentation

在c ++ 11文档中

  

<强>参数

     

first,last - 标识目标字符序列的范围

表示需要iterators来定义范围。

C++11 Documentation Page

为方便起见,这里是文档页面中提供的代码段

#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,我认为,您正在遇到某种无限循环。