我有以下查询:

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)(?:[^':]*:)+:([^']*)

关于c++ - 使用正则表达式C++从单词和定界符之间的字符串中提取所有子字符串,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/51705130/

10-12 14:48
查看更多