I have a list of key value pairs, separated by EOL.
I got Boost Spirit to do what I want for properly formatted lines (i.e. "MyKey : MyValue \r\n MyKey2 : MyValue2").
Now my problem is that I want to skip lines that do not comply. For example:
This is some title line! 
Key1:Value1
Some more gibberish to skip
Key2:Value2
I came up with the following code that I thought would work, but instead, the resulting map is empty and parsing fails.
- In my 
KeyRule, I added '- qi::eol' to avoid eating up the invalid line until the firstKeyValueseparator is encountered. - In my 
ItemRule, bothPairRule's are made optional and theeolis 1 or more to address multiple breaklines. 
I read the following thread:
Why does parsing a blank line with Spirit produce an empty key value pair in map?
It skips the comment line (starting with #) via a custom skipper but in my
case, I want to skip ANY lines not containing the Key Value separator :.
There has to be something elegant.
#include <iostream>
#include <string>
#include <map>
#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/include/std_pair.hpp>
namespace qi = boost::spirit::qi;
template <typename Iterator, typename Skipper = qi::blank_type>
struct KeyValueParser : qi::grammar<Iterator, std::map<std::string, std::string>(), Skipper> {
    KeyValueParser() : KeyValueParser::base_type(ItemRule) {
        ItemRule = -PairRule >> *(+qi::eol >> -PairRule) >> -qi::eol;
        PairRule = KeyRule >> ':' >> ValueRule;
        KeyRule = qi::raw[+(qi::char_ - ':' - qi::eol)];
        ValueRule = qi::raw[+(qi::char_ - qi::eol)];
    }
    qi::rule<Iterator, std::map<std::string, std::string>(), Skipper> ItemRule;
    qi::rule<Iterator, std::pair<std::string, std::string>(), Skipper> PairRule;
    qi::rule<Iterator, std::string(), Skipper> KeyRule;
    qi::rule<Iterator, std::string(), Skipper> ValueRule;
};
int main() {
    const std::string input = " Line To Skip! \r\n  My Key : Value \r\n My2ndKey : Long    Value \r\n";
    std::string::const_iterator iter = input.begin(), end = input.end();
    KeyValueParser<std::string::const_iterator> parser;
    typedef std::map<std::string, std::string> MyMap;
    MyMap parsed_map;
    bool result = qi::phrase_parse(iter, end, parser, qi::blank, parsed_map);
    if (result && (iter == end)) {
        std::cout << "Success." << std::endl;
        for (MyMap::const_iterator pIter = parsed_map.begin(); pIter != parsed_map.end(); ++pIter) {
            std::cout << "\"" << pIter->first << "\" : \"" << pIter->second << "\"" << std::endl;
        }
    } else {
        std::cout << "Something failed. Unparsed: ->|" << std::string(iter, end) << "|<-" << std::endl;
    }
    getchar();
    return 0;
}