[英]Difference between std::regex_match & std::regex_search?
[英]std::regex_search vs std::regex_match
我已经测试(@{[^{}]*})*
匹配@{whatever}
并且它是正确的( https://regex101.com/ )。 因此,尽管正则表达式的可移植性噩梦,我最终构建了正确的 std::regex :
const char *re_str = "@\\{[^\\{\\}]*\\}"; // @{[^{}]*} with curly braces escaped.
可以使用R"()"
简化转义,但这不是问题。 正如我所说,正则表达式有效。 这是一个简单的片段示例,它通过迭代使用regex_search
提取模式:
#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}
有用。
好吧,我想知道是否有更好的方法(性能 pov)。 所以,我尝试使用std::regex_match
而不是迭代std::regex_search
。 我为此使用了一个捕获组,只是将先前的正则表达式包含在()*
中:
const char *re_str = "(@\\{[^\\{\\}]*\\})*"; // (@{[^{}]*})* with curly braces escaped.
这是来源:
#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
它的 output 是空的
我想,这不是使用std::regex_match
的方法,尽管它应该为捕获的组提取匹配项。 也许这次正则表达式无效(我不知道,因为正如我所说,它是可移植性的噩梦)。
所以,
regex_search
是否足够并且值得关注性能?regex_match
是更好的算法还是等效的?regex_match
来源有什么问题?BRs,提前谢谢你
std::regex_search
在输入字符串的任何位置搜索模式。std::regex_match
检查模式是否匹配整个输入字符串。 您的模式与您的整个字符串不匹配,因此std::regex_match
将找不到匹配项。 如果您想匹配整个字符串并提取@{foo}
.*?(@{[^{}]*}).*?(@{[^{}]*}).*
和@{bar}
部分。
- 使用
regex_search
是否足够并且值得关注性能?regex_match
是更好的算法还是等效的?
我不会说在首先比较这两个功能时应该考虑性能。 每个都有或多或少的特定应用领域:当您迭代地将特定模式匹配为输入的子字符串时使用regex_search
,当您需要整个输入以匹配所述模式时使用regex_match
。
当输入是任意长度并且在实例化std::regex
时未知或者如果捕获输入的所有部分所需的模式过于复杂,我会选择regex_search
,否则我会选择regex_match
(如果需要子字符串是通过捕获组获取的)。
- 我的
regex_match
来源有什么问题?
正如其他人已经说过的,它需要匹配整个字符串。 对于您的特定字符串,模式需要看起来像这样:
std::regex re(R"(.*?(@\{[^{}]*\}).*?(@\{[^{}]*\}).*)");
我认为它不像您期望的那样灵活,因此您最好选择已经实现的regex_search
选项。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.