Search code examples
c++parsingboost-spirit

How to parse string only if starts with given number of integers


Given input string "12a", or "a123", I expect "false", "123a" -> true and result=="a", "123ab" -> true and result=="ab" etc.

Here's my attempt:

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

int main(int argc, char* argv[])
{
    std::string s(argv[1]) ;
    int n = 3;//can be runtime parameter
    std::string result;
    auto expr = boost::spirit::qi::omit
        [
            boost::spirit::qi::repeat(n)[boost::spirit::qi::int_] 
        ]   
        >> +boost::spirit::qi::char_("A-Za-z");

    bool b = boost::spirit::qi::phrase_parse(s.begin(), s.end(), expr, boost::spirit::qi::space, result);
    std::cout << std::boolalpha << b << '\n';
    if(b)
    {
        std::cout << result << '\n';
    }
}

Now 123a, 123ab, etc. return false.


Solution

  • boost::spirit::qi::int_ is a greedy parser that will consume all three digits on the first repetition.

    Instead, you should define your own integer parser that will only consume exactly 1 digits like so:

    boost::spirit::qi::uint_parser<unsigned, 10, 1, 1> uint1_p;
    

    And use uint1_p instead of boost::spirit::qi::int_

    Edit: or, yeah... qi::digit does the same thing here.