Reputation: 20756
Why does the following code result in an infinite loop?
#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;
}
}
If I pass iterators to begin
and end
of formula
instead of the formula
itself and update the start
one accordingly, all works as expected:
#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;
}
}
Output
LAST_BID_EURUSD$
LAST_ASK_USDJPY$
The same goes for C++11 regex.
How is it supposed to be used with std::string
objects?
Upvotes: 0
Views: 798
Reputation: 16680
In the first snippet, you're making the same call over and over again.
boost::regex_search(formula, matches, expr)
It's really not surprising that this call gives the same results (i.e, succeeds) each time you call it.
In the second snippet, you are updating the start
iterator each time through the loop, so the "string" that you're searching keeps getting smaller, until, eventually, the search fails, and the loop terminates.
boost::regex_search(start, end, matches, expr)
Upvotes: 3
Reputation: 2625
Requires: Type BidirectionalIterator meets the requirements of a Bidirectional Iterator (24.1.4).
This is the line written in boost
documentation page. You need to provide Iterators
not the object itself.
In c++11 documentation
Parameters
first, last - a range identifying the target character sequence
Means it needs iterators
to define the range.
For your convenience, here is snippet given in the 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;
}
}
Look at 2nd and 3rd line of the IndexClasses
function
Because you are not providing any Iterators
, I think, you are running into some kind of infinite loop.
Upvotes: -1