Is it possible to use std::regex and std::match_results with custom string type?

Viewed 97

I am working on a project that has a custom string type, MyString. I can match on it just fine like this:

MyString getMatch() {
  static const std::regex MyRegularExpression(R"RX(^blah=([a-z0-9]+)$)RX");
  const MyString str = "blah=25";
  std::cmatch match;
  if (std::regex_match(str.GetConstCharPtr(), match, MyRegularExpression))
  {
    return MyString(match[1].str().c_str());
  }
  else {
    return "";
  }
}

But as you can see, I have to convert from cmatchs std::string back to MyString when returning the value. It's not a big deal at all, but I noticed that std::match_results is heavily templated, so I was wondered if it's possible to somehow put MyString to its template arguments to get match results already as MyString.

Is it possible? If yes, how to do it?

1 Answers

Yes, you can use them, if you provide iterators, expected by those methods.

To use regex_match and match_results, your need to provide an iterator, which can be moved in both directions.

template< 
    class BidirIt,
    class Alloc, class CharT, class Traits >
bool regex_match( BidirIt first, BidirIt last,
              std::match_results<BidirIt,Alloc>& m,
              const std::basic_regex<CharT,Traits>& e,
              std::regex_constants::match_flag_type flags =
              std::regex_constants::match_default );

template<
    class BidirIt,
    class Alloc = std::allocator<std::sub_match<BidirIt>>
> class match_results;

Where,

BidirIt must meet the requirements of LegacyBidirectionalIterator.

To meet requirement of iterator, means you should provide a class, which implements interface to increment, decrement and dereference iterator. The simplest example of iterator is a pointer, in case if your MyString stores all chars in a single array. To call regex_match you will need two pointers - at the beginning of array, and one pointing at the next after last element.

Related