Repeat with variable min/max using boost.xpressive

94 Views Asked by At

I'm using boost.xpressive static templates to construct regular expressions that are dynamically concatenated into a final expression.

The dynamic version has a variable-width repeat, but I do need to use the static constructions due to operating in int vectors.

I do need to create repeat<N,M> where N and M are not constants.

How to do it?

1

There are 1 best solutions below

3
On

Unfortunately, C++ only permits you to pass template arguments known at compile time (see here) aka constant expressions.

In this case, it means that the values entered into repeat<N, M> must be literals or constant expressions, so you can't enter just any int of you program.

Its hard to give more concrete advice without seeing any code, but it seems that you are trying to create a regexp which matches for example n repetitions of some group / literal, where n is not yet known at compile time (i.e., depending on some input to your program).

This seems like a strange use case, after all, regular expressions are generally compile time constants (which is the reason for boost-xpressive to exist).

I would recommend using dynamic (ordinary) regular expressions instead. Regular expressions are compiled (preprocessed to speed up matching in the implementation of the regular expression engine) anyways.

Generally a regular expression is generated once and then used many times to match different strings. Thus, the preprocessing step is generally negligible in terms of performance.

Edit

Per your request, here is a dynamic version, contained in a main, which matches based on parameters:

#include <iostream>
#include <sstream>
#include <boost/xpressive/xpressive.hpp>

using namespace boost::xpressive;

int main(int argc, char* argv[])
{
  smatch what;

  int min_match = std::stoi(argv[1]);
  int max_match = std::stoi(argv[2]);

  std::ostringstream expr_buf;

  expr_buf << "a{" << min_match
           << ","
           << max_match
           << "}"
           << "b";

  sregex rex = sregex::compile(expr_buf.str());

  std::string value = argv[3];

  if(regex_match(value, what, rex))
  {
    std::cout << "There was a complete match" << std::endl;
  }
  else
  {
    std::cout << "There was no complete match" << std::endl;
  }

  return 0;
}

For example:

./main 1 3 "aaab" -> "There was a complete match"

./main 1 3 "cab" -> "There was no complete match"

./main 4 5 "aaab" -> "There was no complete match"