problem ze zrozumieniem regex_search

problem ze zrozumieniem regex_search
FV
  • Rejestracja:około 6 lat
  • Ostatnio:3 miesiące
  • Postów:96
0

Witam
Próbuję się nauczyć regexa i nie rozumiem jak działa regex_search. Tzn. wiem że zwraca true jak sekwencja jest substringiem, ale on tam ma jeszcze argument smatch it ego nie kumam jak
to może być użyteczne.

Kopiuj
#include <stdio.h>
#include <regex>
#include <iostream>
#include <string>

int main()
{
    std::regex pattern("^(abc)+.xz");
    std::string text {"abc.xz"};
    std::smatch s;
    if(std::regex_search(text,s,pattern)) {
        std::cout << "found seq" << std::endl;
        for(auto x: s)
            std::cout << x << std::endl;
    }

    return 0;
}

Output spodziewałbym się że będzie abc.xz a jest:
abc.xz
abc

Jak dam powyżej

Kopiuj
std::regex pattern("(abc)");
std::string text {"abc"};

to dwa razy otrzymuję jako output abc. Czemu nie raz?

_13th_Dragon
  • Rejestracja:ponad 19 lat
  • Ostatnio:7 dni
3

std::string text {"abc.xz.abc.xz.abc"};
Zobacz co będzie z tym, sam sobie odpowiesz.


Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.
FV
  • Rejestracja:około 6 lat
  • Ostatnio:3 miesiące
  • Postów:96
0

@_13th_Dragon: To powinno mieć taką funkcjonalność, że ten poniżej algorytm powinien zwracać wektor słów z pominięciem white znaków:

Kopiuj
#include <stdio.h>
#include <regex>
#include <iostream>
#include <string>
#include <vector>

std::vector<std::string> getWords(const std::string& text)
{
    std::vector<std::string> output;
    std::regex pattern("[^\\s*]*");
    std::smatch s;
    if(regex_search(text,s,pattern))
        for(const auto& x : s)
            output.push_back(x);
    
    return output;
}

int main()
{
    std::vector<std::string> vec = getWords("Ala ma kota\ni psa");
    for(const auto& x: vec)
        std::cout << x << std::endl;

    return 0;
}

A zmienna s tylko przechowuje słowo "Ala". Coś totalnie spieprzyli w stlu w tej funkcji regex_search. Lepiej tego w ogóle nie używać do takich rzeczy jak wyżej bo to totalnie inaczej działa niż nazwa wskazuje.
Chyba że może ta funkcja wykonuje swoj algorytm dopóki nie uzna że jest już true i wtedy wychodzi i dlatego mamy tylko słowo Ala bez reszty.

edytowany 1x, ostatnio: fvg
AL
  • Rejestracja:prawie 11 lat
  • Ostatnio:około 3 lata
  • Postów:1493
3

Kliku kliku:

In order to examine all matches within the target sequence, std::regex_search may be called in a loop, restarting each time from m[0].second of the previous call. std::regex_iterator offers an easy interface to this iteration.

Do tego co chcesz zrobić w drugim poście służy regex_iterator
https://godbolt.org/z/jjTKTq3fY

Kopiuj
std::vector<std::string> getWords(const std::string& text)
{
    std::vector<std::string> output;
    std::regex pattern("[^\\s]*");
    std::transform(
        std::sregex_iterator{begin(text), end(text), pattern},
        std::sregex_iterator{}, std::back_inserter(output),
        [](const auto& match) {return match.str();});
    return output;
}

A jak chcesz mogę zaraz wysmażyć Ci wersję na matchu...

EDIT: proszę https://godbolt.org/z/5r4encjY9

Kopiuj

std::vector<std::string> getWords(const std::string& text)
{
    using std::regex_constants::match_not_null;
    std::vector<std::string> output;
    std::regex pattern("[^\\s]*");
    std::smatch s;
    while(regex_search(s.ready() ? s[0].second : begin(text), end(text), s, pattern, match_not_null)) {
        output.push_back(s.str());
    }
    return output;
}


edytowany 4x, ostatnio: alagner
W2
  • Rejestracja:ponad 3 lata
  • Ostatnio:około 3 lata
  • Postów:47
0

To powinno mieć taką funkcjonalność, że ten poniżej algorytm powinien zwracać wektor słów z pominięciem white znaków:
...
Coś totalnie spieprzyli w stlu w tej funkcji regex_search.
...itd

aha
zamiast narzekać przeczytaj z uwagą i zrozumieniem C++ Wyrażenia regularne (C++11 / boost)
a tutaj masz jedno z możliwych rozwiązań swojego problemu

Kopiuj
std::vector<std::string> getWords(const std::string& text)
{
    std::vector<std::string> output;
    string tekst = text;
    const regex pattern("(\\s)");
    tekst = regex_replace(tekst, pattern, " ");
    const regex spaces("([[:space:]]+)");
    tekst = regex_replace(tekst, spaces, " ");
    output.push_back(tekst);
    return output;
}
edytowany 2x, ostatnio: WWA2025
vpiotr
To albo \s+
W2
jak najbardziej, 1 problem dużo rozwiązań

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.