我有以下查询:
std::string query =
"ODR+1"
"DPT+::SFO"
"ARR+::MKE"
"ODR+2"
"DPT+::MKE"
"ARR+::SFO";
我试图从ARR
或DPT
开头的所有段中提取::
之后的值。我写了以下正则表达式[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)
将获取以DPT
或ARR
开头的字符串,但也将其保存,因此结果match[1]
的第一元素具有此值。为避免这种情况,请使用非捕获组:(?: )
问题的第二部分是
.*?
:它捕获了所有内容,包括::
,因此您的正则表达式永远找不到分隔符。您想搜索除:
之外的所有内容,并且可能还搜索不包含'
的所有内容(以避免将错误的部分传播给其他人):(?:[^':]*:)+:
第一部分搜索直到第一个:
的东西,然后检查紧随其后的另一个:
。如果确定此部分没有单个:
,则可以简化它。最后,您将获得所需的字符串:
([^']*)
到第一个'
。括号仅用于捕获内容,因此您可以使用match[1]
检索它(?:DPT|ARR)(?:[^':]*:)+:([^']*)
关于c++ - 使用正则表达式C++从单词和定界符之间的字符串中提取所有子字符串,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/51705130/