2014-12-26 3 views
1

Шаблон функции boost::algorithm::split_regex разбивает одну строку на строки в подстроке исходной строки, которая соответствует шаблону регулярного выражения, который мы передали в 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

бы "POSN = strRequestLine.find_first_of (":»); быть полезным? –

+1

Вышеприведенный код - это просто демонстрация моего вопроса. Интересно, может ли 'split_regex' остановиться при первом найденном шаблоне. Я знаю, как выполнить задачу по-другому, прежде чем публиковать этот вопрос. Меня интересует только использование функции split_regex. Спасибо, в любом случае. – Cody

+0

Возможно, вас заинтересует первый образец, который я перечислил ** [здесь] (http://stackoverflow.com/questions/26902755/skipping-blank-lines-when-reading-line-delimited-list-of-strings/26906134 # comment42375456_26906134) **: [малая функция разбора заголовков HTTP-ответов] (http://paste.ubuntu.com/8989134/). Описание: используйте 'phrase_parse (f, e, token >> ':' >> lexeme [* (char_ - eol)], пробел, ключ, значение)' – sehe

ответ

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"; 
     } 
    } 
} 
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' 
Смежные вопросы