C++11 VS12 regex_search

C++11 VS12 regex_search

本文关键字:search regex VS12 C++11      更新时间:2023-10-16

我正在尝试从字符串中检索数字。字符串格式,如 _0_1_ 我想得到01.

这是我的代码:

std::tr1::regex rx("_(\d+)_");
tstring fileName = Utils::extractFileName(docList[i]->c_str());                 
std::tr1::smatch res;
std::tr1::regex_search(fileName, res, rx);

但在我得到的结果中(更新:这是调试器手表的奇怪输出):

res[0] = 3
res[1] = 1

3从哪里来,我做错了什么?

更新:我将结果输出到屏幕:

for (std::tr1::smatch::iterator it = res.begin(); it < res.end(); ++it){
    std::cout << *it << std::endl;
}

和程序输出:

_0_
0

正则表达式通常返回所有不重叠的匹配项,因此如果您在数字的前面和后面都添加_,您将不会得到所有数字,因为第一个数字后面的下划线不能用作匹配第二个数字之前的下划线

_123_456_
    ^
    This cannot be used twice

只需使用 (\d+) 作为表达式即可获取所有数字(正则表达式默认是"贪婪的",因此无论如何都会找到所有可用的数字)。

似乎是预期的输出。第一个匹配项应该是匹配的整个子字符串,然后第二个(依此类推)应该是捕获组。

如果您想浏览所有比赛,则需要多次致电regex_search以获取每场比赛:

auto it = fileName.cbegin();
while (std::tr1::regex_search(it, fileName.cend(), res, rx)) {
    std::cout << "Found matching group:" << std::endl;
    for (int mm = 1; mm < res.size(); ++mm) {
        std::cout << std::string(res[mm].first, res[mm].second) << std::endl;
    }
    it = res[0].second; // start 1 past the end
}

如果您确实只需要用下划线"包装"的数字,则可以使用肯定断言(?=_)来确保发生这种情况:

// positive assertions are required matches, but are not consumed by the
// matching group.
std::tr1::regex rx("_(\d+)(?=_)");

当对 "//abc_1_2_3.txt" 运行时,检索 1 和 2,但不检索 3。

解决方案:感谢大家,在regex_token_iterator(\d+)的帮助下重写.现在它可以工作:

std::regex_token_iterator<tstring::iterator> rend;
tstring fileName = Utils::extractFileName(docList[i]->c_str());                   
std::tr1::regex_search(fileName, res, rx);              
for (std::regex_token_iterator<std::string::iterator> it(fileName.begin(), fileName.end(), rx); it != rend; ++it) {
        std::cout << " [" << *it << "]";
}