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

时间:2018-08-06 10:05:44

标签: c++ regex

我有以下查询:

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';

1 个答案:

答案 0 :(得分:1)

问题出在您的正则表达式上

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

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

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

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

进行检索。
(?:DPT|ARR)(?:[^':]*:)+:([^']*)