c++ Boost:regex_search expression -发布组合表达式以捕获所有序列

C++ Boost:regex_search expression - Issue combining expressions to catch all sequences

本文关键字:表达式 组合 regex Boost search expression 布组合 -发 c++      更新时间:2023-10-16

我正在尝试编写一个模板解析器,需要拾取(3)个不同的序列集用于字符串替换。

// Each of These Expressions Work Perfect Separately!
// All Sequences start with | pipe. Followed by 
boost::regex expr {"(\|[0-9]{2})"};               // 2 Digits only.
boost::regex expr {"(\|[A-Z]{1,2}+[0-9]{1,2})"};  // 1 or 2 Uppercase Chars and 1 or 2 Digits.
boost::regex expr {"(\|[A-Z]{2})(?!\d)"};        // 2 Uppercase Chars with no following digits.

然而,一旦我尝试将它们组合成单个语句,我就无法正常工作以捕获所有序列。我一定是漏掉了什么。有人能告诉我我漏掉了什么吗?

到目前为止我写的是:

// Each sequence is separated with a | for or between parenthesis. 
boost::regex expr {"(\|[0-9]{2})|(\|[A-Z]{1,2}+[0-9]{1,2})|(\|[A-Z]{2})(?!\d)"};

我使用下面的字符串进行测试,这里可能需要更多的代码。

#include <boost/regex.hpp>
#include <string>
#include <iostream>

std::string str = "|MC01 |U1 |s |A22 |12 |04 |2 |EW |SSAADASD |15";
boost::regex expr {"(\|[0-9]{2})|(\|[A-Z]{1,2}+[0-9]{1,2})|(\|[A-Z]{2})(?!\d)"};
boost::smatch matches;
std::string::const_iterator start = str.begin(), end = str.end();
while(boost::regex_search(start, end, matches, expr))
{
    std::cout << "Matched Sub '" << matches.str()
              << "' following ' " << matches.prefix().str()
              << "' preceeding ' " << matches.suffix().str()
              << std::endl;
    start = matches[0].second;
    for(size_t s = 1; s < matches.size(); ++s)
    {
        std::cout << "+ Matched Sub " << matches[s].str()
                  << " at offset " << matches[s].first - str.begin()
                  << " of length " << matches[s].length()
                  << std::endl;
    }
}

相信这就是你想要的:

const boost::regex expr {"(\|[0-9]{2})|(\|[A-Z]{1,2}+[0-9]{1,2})|(\|[A-Z]{2})"}; // basically, remove the constraint on the last sub

我还建议在expr的标志中明确并传递给regex_search

我还喜欢通过在匹配上添加额外的匹配检查,这消除了让我感到困惑的半匹配模式。

for(size_t s = 1; s < matches.size(); ++s)
{
    if (matches[s].matched)  // Check for bool True/False
    {
        std::cout << "+ Matched Sub " << matches[s].str()
              << " at offset " << matches[s].first - str.begin()
              << " of length " << matches[s].length()
              << std::endl;
    }
}

不带它,匹配在字符串末尾显示长度为0的偏移量。所以我希望这能帮助到其他遇到这种情况的人。

另一个技巧是,在循环中,检查s == 1,2,3引用表达式上的匹配。因为我有(3)个表达式,如果它匹配表达式的第一部分,当匹配为真值时,s将具有1值,否则它将具有2或3。很好!