How to match multiple results using std::regex
This can be done in regex
of C++11
.
Two methos:
- You can use
()
inregex
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
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
Unresolved External Symbol _Imp_Fprintf and _Imp_Iob_Func, Sdl2
How to Parse Space-Separated Floats in C++ Quickly
Best Way to Store Currency Values in C++
How to Forward Declare an Inner Class
Std::String to Float or Double
Checking Cin Input Stream Produces an Integer
How Is a Variable At the Same Address Producing 2 Different Values
How to Get the Index of an Iterator of an Std::Vector
Best Way to Extract a Subvector from a Vector
Why Does C++11'S Lambda Require "Mutable" Keyword For Capture-By-Value, by Default
Why Do We Need a Pure Virtual Destructor in C++
Generating Combinations in C++
How to Succinctly, Portably, and Thoroughly Seed the Mt19937 Prng
Floating Point VS Integer Calculations on Modern Hardware