I am a using a boost regex on a boost circular buffer and would like to "remember" positions where matches occur, what's the best way to do this? I tried the code below, but "end" seems to store the same values all the time! When I try to traverse from a previous "end" to the most recent "end" for example, it doesn't work!
boost::circular_buffer<char> cb(2048);
typedef boost::circular_buffer<char>::iterator ccb_iterator;
boost::circular_buffer<ccb_iterator> cbi(4);
//just fill the whole cbi with cb.begin()
cbi.push_back(cb.begin());
cbi.pushback(cb.begin());
cbi.pushback(cb.begin());
cbi.pushback(cb.begin());
typedef regex_iterator<circular_buffer<char>::iterator> circular_regex_iterator;
while (1)
{
//insert new data in circular buffer (omitted)
//basically reads data from file and pushes it back to cb
boost::circular_buffer<char>::iterator start,end;
circular_regex_iterator regexItr(
cb.begin(),
cb.end() ,
re, //expression of the regular expression
boost::match_default | boost::match_partial);
circular_regex_iterator last;
while(regexItr != last)
{
if((*regexItr)[0].matched == false)
{
//partial match
break;
}
else
{
// full match:
start = (*regexItr)[0].first;
end = (*regexItr)[0].second;
//I want to store these "end" positions to to use later so that I can
//traverse the buffer between these positions (matches).
//cbi stores positions of these matches, but this does not seem to work!
cbi.push_back(end);
//for example, cbi[2] --> cbi[3] traversal works only first time this
//loop is run!
}
++regexItr;
}
}
This isn't quite as much an answer as an attempt to reconstruct what you're doing. I'm making a simple circular buffer initialized from a string, and I traverse regex matches through that buffer and print the matched ranges. All seems to work fine.
I would not recommend storing the ranges themselves in a circular buffer; or at the very least the ranges should be stored in pairs.
Here's my test code:
#include <iostream>
#include <string>
#include <boost/circular_buffer.hpp>
#include <boost/regex.hpp>
#include "prettyprint.hpp"
typedef boost::circular_buffer<char> cb_char;
typedef boost::regex_iterator<cb_char::iterator> cb_char_regex_it;
int main()
{
std::string sample = "Hello 12 Worlds 34 ! 56";
cb_char cbc(8, sample.begin(), sample.end());
std::cout << cbc << std::endl; // (*)
boost::regex expression("\\d+"); // just match numbers
for (cb_char_regex_it m2, m1(cbc.begin(), cbc.end(), expression); m1 != m2; ++m1)
{
const auto & mr = *m1;
std::cout << "--> " << mr << ", range ["
<< std::distance(cbc.begin(), mr[0].first) << ", "
<< std::distance(cbc.begin(), mr[0].second) << "]" << std::endl;
}
}
(This uses the pretty printer to print the raw circular buffer; you can remove the line marked (*)
.)
Update: Here's a possible way to store the matches:
typedef std::pair<std::size_t, std::size_t> match_range;
typedef std::vector<match_range> match_ranges;
/* ... as before ... */
match_ranges ranges;
for (cb_char_regex_it m2, m1(cbc.begin(), cbc.end(), expression); m1 != m2; ++m1)
{
const auto & mr = *m1;
ranges.push_back(match_range(std::distance(cbc.begin(), mr[0].first), std::distance(cbc.begin(), mr[0].second)));
std::cout << "--> " << mr << ", range " << ranges.back() << std::endl;
}
std::cout << "All matching ranges: " << ranges << std::endl;