std::sregex_iterator în C++

Parcurge una câte una toate potrivirile unei expresii regulate dintr-un std::string.

Sintaxă
#include <regex>
std::sregex_iterator inceput(text.begin(), text.end(), re);
std::sregex_iterator sfarsit;  // iteratorul de final

Ce face std::sregex_iterator

std::sregex_iterator găsește pe rând toate potrivirile unui model în text. Construit cu textul și modelul, arată spre prima potrivire; ++ trece la următoarea; un iterator creat fără argumente marchează sfârșitul.

Fiecare element este un std::smatch: it->str() este textul potrivit, (*it)[1] primul grup, it->position() poziția. Cu std::distance(inceput, sfarsit) numeri potrivirile.

Textul trebuie să existe cât timp folosești iteratorul; nu-l construi dintr-un șir temporar.

Exemple

Exemplul 1: Toate adresele de e-mail dintr-un text

info@exemplu. nu are un domeniu complet după punct, așa că nu este găsit.

#include <iostream>
#include <regex>
#include <string>

int main() {
    std::string text = "Scrie-ne la contact@dexblog.ro sau ana.pop@gmail.com, nu la info@exemplu.";
    std::regex email(R"([\w.]+@[\w]+\.[a-z]{2,})");
    for (std::sregex_iterator it(text.begin(), text.end(), email), sfarsit; it != sfarsit; ++it) {
        std::cout << it->str() << " (poziția " << it->position() << ")\n";
    }
}

Rezultat

contact@dexblog.ro (poziția 12)
ana.pop@gmail.com (poziția 35)

Exemplul 2: Suma prețurilor și numărul lor

#include <iostream>
#include <iterator>
#include <regex>
#include <string>

int main() {
    std::string bon = "pâine 4.50 lei; lapte 7.99 lei; ouă 12.00 lei";
    std::regex pret(R"((\d+\.\d{2}) lei)");
    std::sregex_iterator inceput(bon.begin(), bon.end(), pret), sfarsit;

    std::cout << "Produse: " << std::distance(inceput, sfarsit) << '\n';
    double total = 0;
    for (auto it = inceput; it != sfarsit; ++it) {
        total += std::stod((*it)[1].str());
    }
    std::cout << "Total: " << total << " lei\n";
}

Rezultat

Produse: 3
Total: 24.49 lei

Greșeli frecvente

  • Construiești iteratorul dintr-un șir temporar: std::sregex_iterator it(f().begin(), f().end(), re) folosește două șiruri diferite și deja distruse.
  • Uiți că [\w.]+ nu acceptă diacritice: adresele sau cuvintele cu „ș” sunt rupte.

Comenzi înrudite

  • std::regex_search: Caută prima porțiune din text care se potrivește cu modelul, oriunde în text.
  • std::regex: O expresie regulată compilată, folosită pentru verificarea, căutarea și înlocuirea textului.
  • std::regex_match: Verifică dacă tot textul se potrivește cu modelul; std::smatch păstrează grupurile capturate.