std::regex not matching

Viewed 60

I have a regex which by regex101 works correctly:

enter image description here

There are 2 matches, as intended.

Now I'd like to split the same with std's regex_token_iterator:

const std::string text = "This is a test string [more or less] and here is [another].";

const std::regex ws_re("\(?<=\[)(.*?)(?=\])\gm"); // HOW TO WRITE THE ABOVE REGEX IN HERE?

std::copy( std::sregex_token_iterator(text.begin(), text.end(), ws_re, -1),
           std::sregex_token_iterator(),
           std::ostream_iterator<std::string>(std::cout, "\n"));

This compiles fine, but nothing is printed to stdout.

I think the regex has to be written somehow else, can you please point on my mistake?

2 Answers

You can use

const std::regex ws_re(R"(\[([^\]\[]*)\])");

Also, make sure you extract Group 1 values by passing the 1 as the last argument to std::sregex_token_iterator instead of -1 (-1 is used when splitting).

R"(\[([^\]\[]*)\])" is a raw string literal that defines the \[([^\]\[]*)\] regex pattern. It matches

  • \[ - a [ char
  • ([^\]\[]*) - Group 1: any zero or more chars other than [ and ]
  • \] - a ] char.

See the C++ demo:

#include <string>
#include <iostream>
#include <regex>
using namespace std;

int main() {
    const std::string text = "This is a test string [more or less] and here is [another].";
    const std::regex ws_re(R"(\[([^\]\[]*)\])");
    std::copy( std::sregex_token_iterator(text.begin(), text.end(), ws_re, 1),
           std::sregex_token_iterator(),
           std::ostream_iterator<std::string>(std::cout, "\n"));
    
    return 0;
}

You need to escape \ with \\. Also \gm and \ (at the beginning) should be removed to be: (?<=\\[)(.*?)(?=\\])

Related