3

I'm trying to get boost::regex to give me all occurrences of a pattern in a search string. Thought such things would be simple, but leave it to boost and STL to add 10 meta-layers of template obfuscation on top of everything :).

My latest attempt is to use regex_search(), but unfortunately my invocation doesn't seem to be matching any of the overloads. Here's a super-distilled example:

std::string test = "1234567890";
boost::regex testPattern( "\\d" );
boost::match_results<std::string::const_iterator> testMatches;
std::string::const_iterator startPos = test.begin();
while( regex_search( startPos, test.end(), testMatches, testPattern ) ) {
    // Do stuff: record match value, increment start position
}

My call to regex_search() trips intellisense, and fails to compile ( "No instance of 'regex_search' matches the argument list" ).

The overload I'm trying to invoke is:

template <class BidirectionalIterator,
    class Allocator, class charT, class traits>
bool regex_search(BidirectionalIterator first, BidirectionalIterator last,
    match_results<BidirectionalIterator, Allocator>& m,
    const basic_regex<charT, traits>& e,
    match_flag_type flags = match_default );

Which seems to match my invocation fine.

Any ideas are appreciated! As well as alternative ways to do this type of thing. What I ultimately want to do is split a string like:

"0.11,0.22;0.33,0.444;0.555,0.666"

Into a constituent list of float strings that I can then parse.

In any other regex package it'd be simple - run it through an expression like "(?:([0-9.]+)[;,]?)+" and the captured groups will contain the results.

QuadrupleA
  • 876
  • 6
  • 23

2 Answers2

5

The problem is actually that you're mixing iterator types (std::string::iterator and std::string::const_iterator, and since regex_search is a template function, the implicit conversion from iterator to const_iterator is disallowed.

You are correct that declaring test as a const std::string would fix it, as test.end() would now return a const_iterator, instead of iterator.

Alternately, you can do do:

std::string test = "1234567890";
boost::regex testPattern( "\\d" );
boost::match_results<std::string::const_iterator> testMatches;
std::string::const_iterator startPos = test.begin();
std::string::const_iterator endPos = test.end();
while( regex_search( startPos, endPos, testMatches, testPattern ) ) {
    // Do stuff: record match value, increment start position
}

If you've C++11 available, you could also use new std::string::cend member:

std::string test = "1234567890";
boost::regex testPattern( "\\d" );
boost::match_results<std::string::const_iterator> testMatches;
std::string::const_iterator startPos = test.begin();
while( regex_search( startPos, test.cend(), testMatches, testPattern ) ) {
    // Do stuff: record match value, increment start position
}
Nathan Ernst
  • 4,540
  • 25
  • 38
  • Cool, thanks - I'll mark this as the answer, it's a good explanation of what was happening. – QuadrupleA Mar 26 '13 at 00:03
  • Glad you found it helpful. I know from personal experience tracing down these sort of "incompatible" iterator issues can be frustrating, especially when the code seems correct. I sometimes use a form of this error as an interview question. – Nathan Ernst Mar 26 '13 at 20:34
0

OK, figured this one out. If the searched string is declared "const", then the method is found correctly. E.g.:

const std::string test = "1234567890";
QuadrupleA
  • 876
  • 6
  • 23