正则表达式分组与 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]
中的单个字符,然后是<space>:
,它适用于单字符用户名,但仅此而已。第二个捕获组将始终为空,因为您要查找零个或多个字符,而且指定匹配不应该是贪婪的,这意味着零字符匹配是有效的结果。
解决这两个问题你的regex
变成了
std::regex rgx("WEBMSG #([a-zA-Z0-9]+) :(.*)");
但是仅仅实例化regex
和match_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 正则表达式库匹配的主要内容,如果未能解决你的问题,请参考以下文章