std::match_results::size返回什么?
What does std::match_results::size return?
我对下面的c++ 11代码有点困惑:
#include <iostream>
#include <string>
#include <regex>
int main()
{
std::string haystack("abcdefabcghiabc");
std::regex needle("abc");
std::smatch matches;
std::regex_search(haystack, matches, needle);
std::cout << matches.size() << std::endl;
}
我希望它打印出3
,但我得到的是1
。我错过什么了吗?
您得到1
,因为regex_search
只返回1个匹配,而size()
将返回捕获组的数量+整个匹配值。
你的matches
是…
match_results类型的对象(如cmatch或smatch),由该函数填充有关匹配结果和找到的任何子匹配的信息。
如果[regex搜索]成功,它不是空的,并且包含一系列sub_match对象:第一个sub_match元素对应于整个匹配,并且,如果regex表达式包含要匹配的子表达式(即,括号分隔的组),它们对应的子匹配将作为连续的sub_match元素存储在match_results对象中。
下面的代码将找到多个匹配项:
#include <string>
#include <iostream>
#include <regex>
using namespace std;
int main() {
string str("abcdefabcghiabc");
int i = 0;
regex rgx1("abc");
smatch smtch;
while (regex_search(str, smtch, rgx1)) {
std::cout << i << ": " << smtch[0] << std::endl;
i += 1;
str = smtch.suffix().str();
}
return 0;
}
参见IDEONE demo返回abc
3次
由于此方法破坏了输入字符串,因此这里是基于std::sregex_iterator
的另一种选择(当您的主题是std::wstring
对象时应使用std::wsregex_iterator
):
int main() {
std::regex r("ab(c)");
std::string s = "abcdefabcghiabc";
for(std::sregex_iterator i = std::sregex_iterator(s.begin(), s.end(), r);
i != std::sregex_iterator();
++i)
{
std::smatch m = *i;
std::cout << "Match value: " << m.str() << " at Position " << m.position() << 'n';
std::cout << " Capture: " << m[1].str() << " at Position " << m.position(1) << 'n';
}
return 0;
}
参见IDEONE demo,返回
Match value: abc at Position 0
Capture: c at Position 2
Match value: abc at Position 6
Capture: c at Position 8
Match value: abc at Position 12
Capture: c at Position 14
您缺少的是matches
为每个捕获组填充了一个条目(包括作为第0个捕获的整个匹配子字符串)。
如果你写
std::regex needle("a(b)c");
然后你会得到matches.size()==2
, matches[0]=="abc"
,和matches[1]=="b"
。
EDIT:有人对这个答案投了反对票。这可能有多种原因,但如果是因为它不适用于我批评的答案(没有人留下评论来解释这个决定),他们应该注意到W. Stribizew在我写这篇文章两个月后修改了代码,而我直到今天才知道,2021年1月18日。答案的其余部分与我第一次写它时一样。
对于相同的正则表达式,@stribizhev的解具有二次最坏情况复杂度。对于疯狂的(例如"y*"),它不会终止。在某些应用程序中,这些问题可能是等待发生的DoS攻击。下面是一个固定的版本:
string str("abcdefabcghiabc");
int i = 0;
regex rgx1("abc");
smatch smtch;
auto beg = str.cbegin();
while (regex_search(beg, str.cend(), smtch, rgx1)) {
std::cout << i << ": " << smtch[0] << std::endl;
i += 1;
if ( smtch.length(0) > 0 )
std::advance(beg, smtch.length(0));
else if ( beg != str.cend() )
++beg;
else
break;
}
根据我的个人偏好,这将在长度为n的字符串中找到n+1个空正则表达式匹配。您也可以在空匹配后退出循环。
如果您想比较具有数百万个匹配的字符串的性能,请在str
的定义之后添加以下行(不要忘记打开优化),每个版本添加一次:
for (int j = 0; j < 20; ++j)
str = str + str;
- 查找不存在的键时,unordered_map返回什么
- 如果我在 const 函数上使用指针,我可以返回什么?
- 使用枚举作为条件,if 条件将返回什么,真或假?
- 我应该返回什么而不是标准::shared_ptr<>&?
- 当你只使用 return 时,函数返回什么类型;在 c++ 中
- 在C++中,运算符 sizeof 返回什么数据类型?
- ActorItr 迭代器变量中有什么,* ActorItr 返回什么?
- mxGetPr 返回什么?
- 重载运算符返回什么类型的值(对于用户定义的类型):右值还是左值?
- 代码是否有效.如果我想显示第一个元素?如果不是,那么 s.begin() 会返回什么?
- 范围分辨率运算符在类型:: var的情况下返回什么
- fork_rv返回什么
- int* foo(int a)在C 中返回什么
- 当找不到请求的注册表值时,ReggetValue会返回什么
- 我们应该在带有 char *func(char *string) 的函数中返回什么?需要简要说明这与 c 中的 char
- 重载的 QAbstractItemModel::flags 应该为无效的 QModelIndex 返回什么
- 试图在每次输出后使用一个函数摆脱'0',但不确定我可以返回什么
- 查找函数在失败结果中应该返回什么
- 当c 中的矢量容器过载[]运算符时,我对未定义的索引返回什么
- 新运营商在组装中返回什么