正则表达式分组与 C++ 11 正则表达式库匹配

Posted

技术标签:

【中文标题】正则表达式分组与 C++ 11 正则表达式库匹配【英文标题】:Regex grouping matches with C++ 11 regex library 【发布时间】:2015-03-28 18:55:58 【问题描述】:

我正在尝试使用正则表达式进行组匹配。我想从一个大字符串中提取两个字符串。

输入字符串如下所示:

tХB:Username!Username@Username.tcc.domain.com Connected
tХB:Username!Username@Username.tcc.domain.com WEBMSG #Username :this is a message
tХB:Username!Username@Username.tcc.domain.com Status: visible

Username 可以是任何东西。结尾部分this is a message也是如此。

我想要做的是提取井号# 之后的用户名。不是来自字符串中的任何其他位置,因为它也会有所不同。我还想从分号 : 之后的字符串中获取 message

我使用以下正则表达式进行了尝试。但它从不输出任何结果。

regex rgx("WEBMSG #([a-zA-Z0-9]) :(.*?)");
smatch matches;

for(size_t i=0; i<matches.size(); ++i) 
    cout << "MATCH: " << matches[i] << endl;

我没有得到任何匹配。我的正则表达式有什么问题?

【问题讨论】:

是否有必要使用正则表达式来解决这个问题,因为在我看来,流提取功能可以实现这一点。 【参考方案1】:

您的正则表达式不正确,因为两个捕获组都不符合您的要求。第一个是寻找匹配集合[a-zA-Z0-9] 中的单个字符,然后是&lt;space&gt;:,它适用于单字符用户名,但仅此而已。第二个捕获组将始终为空,因为您要查找零个或多个字符,而且指定匹配不应该是贪婪的,这意味着零字符匹配是有效的结果。

解决这两个问题你的regex 变成了

std::regex rgx("WEBMSG #([a-zA-Z0-9]+) :(.*)");

但是仅仅实例化regexmatch_results 对象不会产生匹配,您需要应用regex 算法。由于您只想匹配输入字符串的一部分,因此在这种情况下使用的适当算法是regex_search

std::regex_search(s, matches, rgx);

把它们放在一起

    std::string sR"(
tХB:Username!Username@Username.tcc.domain.com Connected
tХB:Username!Username@Username.tcc.domain.com WEBMSG #Username :this is a message
tХB:Username!Username@Username.tcc.domain.com Status: visible
)";

    std::regex rgx("WEBMSG #([a-zA-Z0-9]+) :(.*)");
    std::smatch matches;

    if(std::regex_search(s, matches, rgx)) 
        std::cout << "Match found\n";

        for (size_t i = 0; i < matches.size(); ++i) 
            std::cout << i << ": '" << matches[i].str() << "'\n";
        
     else 
        std::cout << "Match not found\n";
    

Live demo

【讨论】:

【参考方案2】:
"WEBMSG #([a-zA-Z0-9]) :(.*?)"

此正则表达式将仅匹配字符串,其中包含 1 个字符长度的用户名和分号后的任何消息,但第二组将始终为空,因为试图找到从 0 到无限的任何字符的非贪婪匹配较少。

这应该可行:

"WEBMSG #([a-zA-Z0-9]+) :(.*)"

【讨论】:

以上是关于正则表达式分组与 C++ 11 正则表达式库匹配的主要内容,如果未能解决你的问题,请参考以下文章

javascript 正则表达式之分组与前瞻匹配详解

C++ Primer 5th笔记(chap 17 标准库特殊设施)正则表达式

正则表达式入门环视

正则表达式第三回--模式分组与前瞻

如何在 C++ 中对多个正则表达式使用正则表达式“分组”?

JS 正则表达式正面向后看不匹配