How to Match Multiple Results Using Std::Regex

How to match multiple results using std::regex

This can be done in regex of C++11.

Two methos:

  1. You can use () in regex to define your captures.

Like this:

    string var = "first second third forth";

const regex r("(.*) (.*) (.*) (.*)");
smatch sm;

if (regex_search(var, sm, r)) {
for (int i=1; i<sm.size(); i++) {
cout << sm[i] << endl;
}
}

See it live: http://coliru.stacked-crooked.com/a/e1447c4cff9ea3e7


  1. You can use sregex_token_iterator():

     string var = "first second third forth";

    regex wsaq_re("\\s+");
    copy( sregex_token_iterator(var.begin(), var.end(), wsaq_re, -1),
    sregex_token_iterator(),
    ostream_iterator<string>(cout, "\n"));

See it live: http://coliru.stacked-crooked.com/a/677aa6f0bb0612f0

C++ std::regex Regular Expressions Finding multiple matches

Try using a negated character class instead. I get the feeling your character classes aren't behaving like you think they are...

subjectRx("OU=[^,]*", std::regex_constants::icase);

[^,]* will match all characters except a comma.

As for the matches, try using a loop:

while (std::regex_search (mySubject,OuMatches,subjectRx)) {
// do something
}

I don't know much C++, but I found this documentation page which I think should be a bit more useful.

The piece of code it has here is

while (std::regex_search (s,m,e)) {
for (auto x:m) std::cout << x << " ";
std::cout << std::endl;
s = m.suffix().str();
}

EDIT: I just realise that you can have commas in the parameters like in O=, which won't be working with [^,]. Instead, you can use this regex:

OU=(?:[^,]|,(?!(?:[^"]*"[^"]*"[^"]*)*$))*

You can see an example with O= here.

C++ regex finds only 1 sub match

Being called once, regex_search returns only the first match in the match variable. The collection in match comprises the match itself and capture groups if there are any.

In order to get all matches call regex_search in a loop:

while(regex_search(strr, match, rgx))
{
std::cout << match[0] << std::endl;
strr = match.suffix();
}

Note that in your case the first capture group is the same as the whole match so there is no need in the group and you may define the regex simply as [0-9] (without parentheses.)

Demo: https://ideone.com/pQ6IsO

Match regex multiple times in one std::string

You could use the last parameter in regex_token_iterator as an array of subgroups (considering 2 groups (number and color) you want).

The following snippet doesn't do any error checking and assumes you input string is valid:

using Pair = std::pair<int, std::string>;
Pair p;
const int subgroups[] = {1,2};
std::vector < Pair> results; // Your desired result
std::regex_token_iterator<std::string::iterator> c
{ test.begin(), test.end(), regex_it, subgroups };
std::regex_token_iterator<std::string::iterator> rend;

while (c!=rend) {
// Do some sort of error handling here
p.first = std::stoi(*c++);
p.second = *c++;
results.push_back(p);
}

std::cout << results.size(); // 4

Demo here

C++: regex matching code, printing multiple matches?

is not -. That are two different symbols. You have in the code and - in the input. Here I fixed the code:

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

int main(int argc, char *argv[])
{
// ZIP code pattern: XXddddd-dddd and variants
regex pat (R"(\w{2}\s*\d{5}(-\d{4})?)");
int lineno = 0;

for (string line; getline(cin,line);) {
++lineno;
smatch matches; // matched strings go here
if (regex_search(line, matches, pat)) // search for pat in line
for (auto p : matches) {
cout << p << " ";
}
cout << endl;
// cout << lineno << ": " << matches[0] << '\n';
}

return 0;
}

C++ regex both matches and groups

The way it is done is to iterate using regex_search() which has

many prototypes.

Regex iterator stuff reverts to this behind the scenes.

Here you go.

There are many more answers to how to use regex in C++,

just let me know.

std::string::const_iterator start = str.begin();
std::string::const_iterator end = str.end();
std::smatch m;

std::regex rx( "([0-9]+)/([0-9]*)/([0-9]*)" );

while ( std::regex_search( start, end, m, rx ) )
{
std::string sWholeMatch = m[0].str();
std::string sGrp1 = m[1].str();
std::string sGrp2 = m[2].str();
std::string sGrp3 = m[3].str();

int lenGrp1 = sGrp1.length();
int lenGrp2 = sGrp2.length();
int lenGrp3 = sGrp3.length();

start = m[0].second;
}


Related Topics



Leave a reply



Submit