如何只split_regex一次

How to split_regex only once?

本文关键字:regex 一次 split      更新时间:2023-10-16

函数模板boost::algorithm::split_regex将单个字符串拆分为原始字符串子字符串上的字符串,该字符串与我们传递给split_regex的正则表达式模式匹配。问题是:如何在匹配的第一个子字符串上只拆分一次?也就是说,split_regex第一次分裂后是否有可能停止?请参阅以下代码。

#include <boost/algorithm/string/regex.hpp>
#include <boost/format.hpp>
#include <boost/regex.hpp>
#include <iostream>
#include <locale>
int main(int argc, char *argv[])
{
    using namespace std;
    using boost::regex;
    locale::global(locale(""));
    // Create a standard string for experiment.
    string strRequestLine("Host: 192.168.0.1:12345");
    regex pat(R"(:s*)", regex::perl | boost::regex_constants::match_stop);
    // Try to split the request line.
    vector<string> coll;
    boost::algorithm::split_regex(coll, strRequestLine, pat);
    // Output what we got.
    for (const auto& elt : coll)
        cout << boost::format("{%s}n") % elt;
    // Exit the program.
    return 0;
}

应该在哪里修改代码以获得类似输出

{Host}
{192.168.0.1:12345}

而不是电流输出

{Host}
{192.168.0.1}
{12345}

有什么建议/提示吗?谢谢。

请注意,我不是在问如何使用其他函数或模式来做到这一点。我问split_regex是否有可能只分裂一次然后停止。因为regex对象似乎有能力在第一个匹配时停止,我想知道如果给它一些适当的标志,它可能会在第一个匹配时停止。

对于您的特定输入,似乎简单的解决方法是更改模式以变得R"(:s+)"。当然,这假设 Host: 之后至少有一个空格,IP 地址和端口之间没有空格。

另一种选择是不使用split_regex()而是std::regex_match()

#include <iostream>
#include <regex>
#include <string>
int main()
{
    std::string strRequestLine("Host: 192.168.0.1:12345");
    std::smatch results;
    if (std::regex_match(strRequestLine, results, std::regex(R"(([^:]*):s*(.*))"))) {
        for (auto it(++results.begin()), end(results.end()); it != end; ++it) {
            std::cout << "{" << *it << "}n";
        }
    }
}

从我的评论扩展:

您可能对我在此处列出的第一个示例感兴趣:小型 HTTP 响应标头解析函数。摘要:使用phrase_parse(f, e, token >> ':' >> lexeme[*(char_ - eol)], space, key, value)

下面是一个简单的示例:

住在科里鲁

#include <boost/spirit/include/qi.hpp>
namespace qi = boost::spirit::qi;
namespace {
    typedef std::string::const_iterator It;
    // 2.2 Basic Rules (rfc1945)
    static const qi::rule<It, std::string()> rfc1945_token = +~qi::char_( " t><@,;:\"/][?=}{:"); // FIXME? should filter CTLs
}
#include <iostream>
int main()
{
    std::string const strRequestLine("Host: 192.168.0.1:12345");
    std::string::const_iterator f(strRequestLine.begin()), l(strRequestLine.end());
    std::string key, value;
    if (qi::phrase_parse(f, l, rfc1945_token >> ':' >> qi::lexeme[*(qi::char_ - qi::eol)], qi::space, key, value))
        std::cout << "'" << key << "' -> '" << value << "'n";
}

指纹

'Host' -> '192.168.0.1:12345'