使用正则表达式c++从单词和分隔符之间的字符串中提取所有子字符串

Extract all substrings from a string that are between a word and a delimiter using regex c++

本文关键字:字符串 提取 之间 分隔符 正则表达式 c++ 单词      更新时间:2023-10-16

我有以下查询:

std::string query =
"ODR+1"
"DPT+::SFO"
"ARR+::MKE"
"ODR+2"
"DPT+::MKE"
"ARR+::SFO";

我试图从以ARRDPT开头的所有段中提取::之后的值。我编写了以下正则表达式[DPT|ARR]+::(.*)。当我在regex101 上测试它时,它起了作用

当我编写以下C++代码时。我得到了以下输出:

DPT+::SFO'ARR+::MKE'ODR+2'DPT+::MKE'ARR+::SFO'

输出是错误的,我真的只想提取SFO和MKO。如何修改正则表达式查询以仅提取这些模式


#include <regex>
#include <iostream>
int main()
{
std::string query =
"ODR+1'"
"DPT+::SFO'"
"ARR+::MKE'"
"ODR+2'"
"DPT+::MKE'"
"ARR+::SFO'";

std::regex regulaExpression("(DPT|ARR).*::(.*)'");
std::sregex_iterator iter(query.begin(), query.end(), regulaExpression);
std::sregex_iterator end;
while(iter != end)
{
std::cout << iter->str() << std::endl;
++iter;
}
}

更新

我更新了代码:

#include <regex>
#include <iostream>
#include <cstring>
int main()
{  
const char *target  =
"ODR+1'"
"DPT+::SFO'"
"ARR+::MKE'"
"ODR+2'"
"DPT+::MKE'"
"ARR+::SFO'";
std::regex rgx("(DPT|ARR).*?::(.*?)'");
for(auto it = std::cregex_iterator(target, target + std::strlen(target), rgx);
it != std::cregex_iterator();
++it)
{
std::cmatch match = *it;
std::cout << match[2].str() << 'n';
}

return 0;
}

现在它允许我检索以下内容。这正是我想要的。但我不知道为什么它有效。

SFo                                                                                                                                                                                     
MKE                                                                                                                                                                                     
MKE                                                                                                                                                                                     
SFO

为什么我必须使用std::cout << match[2].str() << 'n';

问题出在正则表达式上:

(DPT|ARR).*?::(.*?)'

第一部分(DPT|ARR)将获得以DPTARR开头的字符串,但也将保存它,因此结果match[1]的第一个元素具有此值。为了避免这种情况,请使用非捕获组:(?: )

第二部分.*?是问题所在:它捕获了所有内容,包括::,所以正则表达式永远找不到分隔符。您想搜索除:之外的所有内容,也可能不搜索'(以避免错误的部分传播给其他人(:(?:[^':]*:)+:
第一部分搜索第一个:之前的内容,然后检查紧接着还有另一个:。如果你确定这个部分没有单一的:,你可以简化它

最后,您将获得所需的字符串:([^']*),直到第一个'。括号只用于捕获内容,因此您可以使用match[1]检索它

(?:DPT|ARR)(?:[^':]*:)+:([^']*)