我有以下查询:
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';
答案 0 :(得分:1)
问题出在您的正则表达式上
(DPT|ARR).*?::(.*?)'
第一部分(DPT|ARR)
将获得以DPT
或ARR
开头的字符串,但还将保存它,因此结果match[1]
的第一元素具有此值。为避免这种情况,请使用非捕获组:(?: )
问题.*?
的第二部分:它捕获了所有内容,包括::
,因此您的正则表达式永远找不到分隔符。您想搜索除:
之外的所有内容,并且可能还搜索不包含'
的所有内容(以避免将错误的部分传播给其他人):(?:[^':]*:)+:
第一部分搜索直到第一个:
为止的内容,然后检查之后是否还有另一个:
。如果您确定此部分没有单个:
,则可以简化它。
最后,您将获得所需的字符串:([^']*)
,直到第一个'
。括号仅用于捕获内容,因此您可以使用match[1]
(?:DPT|ARR)(?:[^':]*:)+:([^']*)