I have implemented the following code to try and count the number of matches in the given string; in this case it should be 1.
#include <iostream>
#include <string>
#include <regex>
unsigned countMatches(std::string text, std::regex expr);
int main()
{
std::string phrase = "Hello world";
std::regex pattern = std::regex("world");
std::cout << countMatches(phrase, pattern) << std::endl;
return 0;
}
unsigned countMatches(std::string text, std::regex expr)
{
std::smatch matches;
while(std::regex_search(text, matches, expr))
text = matches.suffix().str();
return matches.size();
}
However it always prints 0 and I can't see why.
CodePudding user response:
If you just want to iterate over the input string, and count a number of matches, you can use std::sregex_iterator
.
unsigned countMatches(const std::string& text, std::regex expr) {
unsigned ret{};
for (auto it = std::sregex_iterator(text.begin(), text.end(), expr);
it != std::sregex_iterator{};
it, ret);
return ret;
}
// Outputs: 1
CodePudding user response:
However it always prints 0 and I can't see why.
You call regex_search
in a while loop. The body of the loop (eventhough wrongly indented) is updating text
. The first iteration does find 1 match. But then you update text to be an empty string (the suffix of the match) and in the next iteration there are 0 matches. This is the value your function returns.
Instead you should accumulate the number of matches:
#include <iostream>
#include <string>
#include <regex>
size_t countMatches(std::string text, std::regex const & expr)
{
std::smatch matches;
size_t result{ 0 };
while (std::regex_search(text, matches, expr))
{
result = matches.size(); // <--- accumulate number of matches
text = matches.suffix().str();
}
return result;
}
int main()
{
std::string phrase = "Hello world";
std::cout << countMatches(phrase, std::regex("world")) << std::endl;
std::cout << countMatches(phrase, std::regex("o")) << std::endl;
return 0;
}
Output:
1
2
Note that I changed the return value to size_t
as this is the type of matches.size()
. I also added const &
to the expr
parameter to avoid a copy.