std::smatch返回什么,你应该如何使用它?

19

字符串 "我5岁了"

正则表达式 "(?!am )\d"

如果您前往http://regexr.com/并将正则表达式应用于该字符串,您将获得数字5。 我希望使用std :: regex获得此结果,但我不理解如何使用匹配结果,而且可能还需要更改正则表达式。

std::regex expression("(?!am )\\d");
std::smatch match;
std::string what("I am 5 years old.");
if (regex_search(what, match, expression))
{
     //???
}

1
你的正则表达式是错误的,因为5永远不会等于a(?!am )\d\d相同。 - Wiktor Stribiżew
我需要获取单词“am”和空格后面的数字。 - Kimi
1
为什么不使用正则表达式搜索"I am (\d)+ years old"并使用捕获呢? - Mateen Ulhaq
我只是举了一个简单的例子,目标是将工作正则表达式移植到C++。实际上,我们有一些文本,其中包含一个魔术词后跟一个空格和数字。我需要获取那个数字。 - Kimi
1个回答

12

std::smatchmatch_results 类模板的实例,用于对字符串对象(使用 string::const_iterator 作为其迭代器类型)进行匹配。这个类的成员与 match_results 相同,但使用 string::const_iterator 作为其 BidirectionalIterator 模板参数。

std::match_results 支持 operator[]

如果 n > 0n < size(),则返回一个引用,该引用表示目标序列中第 n 个捕获 子表达式 匹配的部分所代表的 std::sub_match。 如果 n == 0,则返回一个引用,该引用表示整个匹配正则表达式所匹配的目标序列的部分所代表的 std::sub_match。 如果 n >= size(),则返回一个引用,该引用表示未匹配的子表达式(目标序列的空子范围)所代表的 std::sub_match
在你的情况下,regex_search 仅找到 第一个匹配项,然后 match[0] 包含整个匹配文本,match[1] 将包含使用第一个捕获组(第一个括号模式部分)捕获的文本等。但是,在此情况下,您的正则表达式不包含捕获组。
在这里,您需要使用一个捕获机制,因为 std::regex 不支持向后查找。您使用了一个前瞻,它检查当前位置后面的文本,并且您拥有的正则表达式并没有做您认为它会做的事情。
因此,请使用 以下代码
#include <regex>
#include <string>
#include <iostream>
using namespace std;

int main() {
    std::regex expression(R"(am\s+(\d+))");
    std::smatch match;
    std::string what("I am 5 years old.");
    if (regex_search(what, match, expression))
    {
         cout << match.str(1) << endl;
    }
    return 0;
}

在这里,模式是am\s+(\d+)"。它匹配am,1个或多个空格,然后使用(\d+)捕获1个或多个数字。在代码中,match.str(1)允许访问使用捕获组捕获的值。由于模式中只有一个(...),即一个捕获组,其ID为1。因此,str(1)返回捕获到该组中的文本。
原始字符串字面量(R"(...)")允许使用单个反斜杠来进行正则表达式转义(如\d\s等)。

感谢,出于某种原因我需要调用 match.str(2) 来获取数字。match.str(1) 返回 "am 5"。我使用的是带有 Visual Studio 2012 (v110) 平台工具集的 VS2015。 - Kimi
1
@Kimi 这是因为你可能没有访问原始字符串字面量的权限。如果你使用VS2015工具集,你将会有这个权限,std::regex expression(R"(am\s+(\d+))"); 将会抓取数字到第一组中。你可能正在使用 "(am\\s+(\\d+))",一个常规字符串字面量,其中第一个 ( 和最后一个 ) 不能使用。移除它们,你将会得到第一组的结果。R"(am\s+(\d+))" = "am\\s+(\\d+)" - Wiktor Stribiżew
是的,使用 R"" 无法编译。我不得不删除 R 并添加额外的 \,但忘记删除额外的 ( 和 )。现在一切都正常了,非常感谢。 - Kimi
你的意思是它没有后顾之忧吗?它有反向引用吗? - Passer By
哎呀,误解了很多。 - Passer By
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接