2015-08-28 3 views
2

Я хотел был бы иметь возможность разделить строку на две части, left и right, при первом возникновении separator. Например, с # в качестве разделителя left#right#more результатом будет left и right#more.Разделить строку на две части с помощью C++ Boost?

У меня есть способ сделать это:

void misc::split(const string &input, string &left, string &right, char separator) 
{ 
    int index = input.find(separator); 
    if (index == string::npos) 
    { 
     left = input; 
     right.erase(); 
    } 
    else 
    { 
     right = input.substr(index + 1); 
     left = input.substr(0, index); 
    } 
} 

Теперь я начал использовать подталкивание и хотел бы, чтобы сжать этот довольно длинный код на что-то более элегантное. Я знаю о boost::split(), но это дает мне три части в исходном примере (left, right и more).

Любые предложения?

+0

Вас могут пригласить в это [предложение] (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3510.html) и [это] (http: // stackoverflow.com/questions/5734304/c-boost-split-string). –

ответ

5

Я предсказываю, что это не будет значительно лучше, потому что если внутренняя сложность.

Тем не менее, вот пример на основе духа:

static void split(const std::string &input, std::string &left, std::string &right, char separator) 
{ 
    using namespace boost::spirit::qi; 

    parse(input.begin(), input.end(), *~char_(separator) >> separator >> *char_, left, right); 
} 

С полным тестом:

Live On Coliru

#include <boost/spirit/include/qi.hpp> 

struct misc { 
    static void split(const std::string &input, std::string &left, std::string &right, char separator) 
    { 
     using namespace boost::spirit::qi; 

     parse(input.begin(), input.end(), *~char_(separator) >> separator >> *char_, left, right); 
    } 
}; 

int main() { 
    for (std::string s : { 
      "", 
      "a", 
      "a;", 
      "a;b", 
      ";b", 
      ";", 
      "a;b;", 
      ";;" }) 
    { 
     std::string l,r; 
     misc::split(s,l,r,';'); 
     std::cout << "'" << s << "'\t-> l:'" << l << "'\tr:'" << r << "'\n"; 
    } 
} 

распечатки:

'' -> l:'' r:'' 
'a' -> l:'a' r:'' 
'a;' -> l:'a' r:'' 
'a;b' -> l:'a' r:'b' 
';b' -> l:'' r:'b' 
';' -> l:'' r:'' 
'a;b;' -> l:'a' r:'b;' 
';;' -> l:'' r:';' 
+0

Спасибо за подсказку! Не уверен, что я понимаю, как это работает, но это просто означает, что мне интересно читать. :-) По крайней мере, я могу сказать, что он (а) работает, и (б) меньше строк кода. – Anders

+0

Да. Дух - это не что-то, что нужно «заглядывать». Это концептуально просто. Вы должны прочитать там только введение в учебник. Действительно, я начал с «Я предсказываю, что это не будет значительно лучше» по какой-то причине. Я лично написал бы то, что у вас было. – sehe

Смежные вопросы