函数模板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
对象似乎有能力在第一次匹配时停止,我想知道如果提供一些正确的标志,它可能会在第一次匹配时停止。
答案 0 :(得分:0)
对于您的具体输入,似乎简单的解决方法是将模式更改为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";
}
}
}
答案 1 :(得分:0)
扩展我的评论:
您可能对我列出的第一个示例感兴趣 here :small HTTP response headers parsing function。摘要:使用
phrase_parse(f, e, token >> ':' >> lexeme[*(char_ - eol)], space, key, value)
这是一个简单的示例:
<强> Live On Coliru
#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'