I have tested (@{[^{}]*})* to match @{whatever} and it is correct (https://regex101.com/).
So, in spite of portability nightmare for regular expressions, I finally built the proper std::regex with:
const char *re_str = "@\\{[^\\{\\}]*\\}"; // @{[^{}]*} with curly braces escaped.
Escapes could be simplified using R"()" but that's not the question. As I said, the regex works. Here a simple snippet example which extracts the pattern using regex_search through iteration:
#include <iostream>
#include <string>
#include <regex>
int main () {
std::string str = "Bye @{foo} ! hi @{bar} !";
std::smatch matches;
std::string::const_iterator it( str.cbegin() );
const char *re_str = "@\\{[^\\{\\}]*\\}"; // @{[^{}]*} with curly braces escaped
// or: const char *re_str = R"(@\{[^\{\}]*\})";
try {
std::regex re(re_str);
while (std::regex_search(it, str.cend(), matches, re)) {
std::cout << matches[0] << std::endl;
it = matches.suffix().first;
}
}
catch (std::exception& e) {
std::cout << e.what() << std::endl;
return 1;
}
return 0;
}
Output:
g++ regex_search.cc && ./a.out
@{foo}
@{bar}
it works.
Well, I'm wondering if there is any better approach (performance pov).
So, I tried with std::regex_match instead of iterating on std::regex_search.
I used a capture group for that, just enclosing previous regular expression within ()*:
const char *re_str = "(@\\{[^\\{\\}]*\\})*"; // (@{[^{}]*})* with curly braces escaped.
This is the source:
#include <iostream>
#include <string>
#include <regex>
int main () {
std::string str = "Bye @{foo} ! hi @{bar} !";
std::smatch matches;
std::string::const_iterator it( str.cbegin() );
const char *re_str = "(@\\{[^\\{\\}]*\\})*"; // (@{[^{}]*})* with curly braces escaped.
try {
std::regex re(re_str);
if (std::regex_match(str, matches, re)) {
for (int k=0; k<matches.size(); k++) std::cout << "[" << k << "]: " << matches.str(k) << std::endl;
}
}
catch (std::exception& e) {
std::cout << e.what() << std::endl;
return 1;
}
return 0;
}
Output:
g++ regex_match.cc && ./a.out
Its output is empty !!!
I imagine, that's not the way to use std::regex_match although it is supposed to extract matches for captured group.
Perhaps the regex this time is invalid (I don't know because, as I said, it is a portability nightmare).
So,
- is using
regex_searchenough and worths the performance concern ? - Is
regex_matchbetter algorithm or is it equivalent ? - What's wrong with my source for
regex_match?
BRs, thank you in advance
regex_matchyour regex has to match the entire input string, your regex doesn't match the whole string: regex101.com/r/4HzmeB/1regex_matchmatches the whole string