Boost дух: как разобрать строку пар значений в картуи назад? - PullRequest
2 голосов
/ 22 июля 2011

Таким образом, имея строку типа remixsettings_bits=1; wysiwyg=1,2,3,abc; remixclosed_tabs=0; remixgroup_closed_tabs=786432; remixlang=0; remixchk=5; remixsid=35d4f9907281708019490d07728c27ca5c10e5de7a869c322222225e3219e; audio_vol=100 Интересно, как разобрать их в карту name <-> value, используя boost :: spirit, и как быть в состоянии записать их обратно, используя boost :: spirit?

Обновление: Итак, что я сделал:

#include <iostream>
#include <sstream>
#include <string>
#include <map>
//...

std::map<std::string, std::string> user_control::parse_cookie( std::string cookie_data )
{
    std::map<std::string, std::string> parsed_cookie;
    std::string token, token2;
    std::istringstream iss(cookie_data);
    while ( getline(iss, token, ' ') )
    {
        std::string name, val;
        std::istringstream iss2(token);
        int num = 0 ;
        while ( getline(iss2, token2, '=') )
        {
            if ( num == 0)
            {
                name = token2;
                num++;
            }
            else
            {
                val = token2;
                std::string::iterator it = val.end() - 1;
                if (*it == ';')
                    val.erase(it);

            }
        }
        std::cout << "name: " << name <<  " value: " << val << std::endl;
        parsed_cookie.insert(std::pair<std::string, std::string>(name, val));
    }
    return parsed_cookie;
}

но мне действительно интересно, как перенести мой код в boost :: spirit code.

Ответы [ 2 ]

6 голосов
/ 22 июля 2011

Это должно сработать, разобрав пары и распечатав результаты, используя Карму, хотя, вероятно, нам обоим стоит прочитать статью Хартмута!

#include <boost/spirit/include/qi.hpp>         // Parsing
#include <boost/spirit/include/karma.hpp>      // Generation
#include <boost/fusion/adapted/std_pair.hpp>   // Make std::pair a fusion vector

int main( int argc, char**argv)
{
  using namespace boost::spirit;
  std::string str = "keyA=value1; keyB=value2;keyC=value3;";

  std::map<std::string,std::string> contents;
  std::string::iterator first = str.begin();
  std::string::iterator last  = str.end();

  const bool result = qi::phrase_parse(first,last, 
   *( *(qi::char_-"=")  >> qi::lit("=") >> *(qi::char_-";") >> -qi::lit(";") ),
    ascii::space, contents);                                  

  assert(result && first==last);

  std::cout << karma::format(*(karma::string << '=' <<
               karma::string << karma::eol), contents);
}
3 голосов
/ 22 июля 2011

Вы видели эту статью парсера и эту статью генератора ?AFAICT, они точно объясняют, что ты пытаешься сделать.

...