Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get every regex match one by one with their positions

Tags:

c++

regex

I need to get all regex matches and their positions.

For example, I have this regex:

std::regex r("(a)|(b)|(c)");

And this input text:

std::string text("abcab");

Now I want to loop the matches there in every loop I can access all occurrences from one match. So in first loop I could get "a" at position 0 and "a" at position 3. In second loop it'd be "b" at 1 and "b" at 4. And in third loop it'd be "c" at position 2. How can I do this?

Currently I have every regex part separately (regex for (a), (b) and (c)) and go through them one by one. But there are quite many of them so I'm looking for better/faster solution.

like image 720
Martin Heralecký Avatar asked Dec 08 '25 16:12

Martin Heralecký


1 Answers

You can declare string vectors to store the captured values in, and then check which alternative branch matched, and add it to the corresponding vector.

Here is a C++ demo:

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

int main() {
    std::regex r("(a)|(b)|(c)");
    std::string s = "abcab";
    std::vector<std::string> astrings; // Declare the vectors to 
    std::vector<std::string> bstrings; // populate with the contents
    std::vector<std::string> cstrings; // of capturing groups

    for(std::sregex_iterator i = std::sregex_iterator(s.begin(), s.end(), r);
           i != std::sregex_iterator();
           ++i)
    {
        std::smatch m = *i;
        if (m[1].matched) {                 // Check if Group 1 matched and 
            astrings.push_back(m[1].str()); // Put a value into a string vector
        }
        else if (m[2].matched) {            // Check if Group 2 matched and 
            bstrings.push_back(m[2].str()); // Put a value into b string vector
        }
        else if (m[3].matched) {             // Check if Group 3 matched and 
            cstrings.push_back(m[3].str());  // Put a value into c string vector
        }
    }

    // Printing vectors - DEMO
    for (auto i: astrings)
        std::cout << i << ' ';
    std::cout << "\n";
    for (auto i: bstrings)
        std::cout << i << ' ';
    std::cout << "\n";
    for (auto i: cstrings)
        std::cout << i << ' ';

    return 0;
}

You may also consider using std::regex_constants::optimize flag when declaring the regexp (see Galik's comment).

like image 50
Wiktor Stribiżew Avatar answered Dec 17 '25 04:12

Wiktor Stribiżew



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!