Search code examples
c++boostboost-xpressive

Boost Xpressive sregex assignment and capture group issue


I notice strange behavior in the boost xpressive sregex assignments. See the code below. The first code snippet that does not work has sregex has object preliminary assignments and then being used in the main expression later. The second code snippet that does work well has no prior sregex assignments (except the final main one). Please let me know if I am using the boost xpressive api incorrectly.

Code that does not work

  mark_tag Value1(1), Value2(2), Value3(3), Value4(4), Value5(5), Value6(6), Value7(7);
  boost::xpressive::sregex name,multicast,rtsp;

  name = ( (Value1 =  (+boost::xpressive::set[_w|_d|'-'|'_'|as_xpr(' ')]) )  >> ',' );

  name1 =
       ( (Value2 = icase(as_xpr("mark1:") ) )
    >> (Value3 =  (+boost::xpressive::set[_d|'.']) )
    >> ':'
    >> (Value4 =  (+boost::xpressive::set[_d]) ) >> optional(as_xpr(",")) );

  name2 =
       ( (Value5 = icase(as_xpr("mark2:") ) )
    >> (Value6 =  (+boost::xpressive::set[_d|'.']) )
    >> ':'
    >> (Value7 =  (+boost::xpressive::set[_d]) ) >> optional(as_xpr(",")) ) ;

   boost::xpressive::sregex pt = bos
    >> (
    name
    >> repeat<0,2>(
    name1
    |
    name2)
    )
    >> eos;


    boost::trim(string_to_parse);
    smatch what;
    if ( !regex_search(string_to_parse, what, pt)) {
        std::stringstream ss;
        ss << "Unable to parse: " << string_to_parse;
        throw parse::MyException(ss.str());
    }

    std::string Value1_str = what[Value1]; // print them later
    std::string Value2_str = what[Value2]; // print them later
    std::string Value3_str = what[Value3]; // print them later
    std::string Value4_str = what[Value4]; // print them later
    std::string Value5_str = what[Value5]; // print them later
    std::string Value6_str = what[Value6]; // print them later
    std::string Value7_str = what[Value7]; // print them later

string_to_parse = NameX,mark1:192.168.1.100:5555,mark2:192.168.1.101:5556; (fails parsing) Meaning what[<>] does not contain any value.

Code that works

   mark_tag Value1(1), Value2(2), Value3(3), Value4(4), Value5(5), Value6(6), Value7(7);
   sregex pt = bos
    >> (
    ( (Value1 =  (+boost::xpressive::set[_w|_d|'-'|'_'|as_xpr(' ')]) ) >> ',' )
    >> repeat<0,2>(
    ( (Value2 = icase(as_xpr("mark1:") ) ) >> (Value3 =  (+boost::xpressive::set[_d|'.']) ) >> ':' >> (Value4 =  (+boost::xpressive::set[_d]) ) >> optional(as_xpr(",")) )
    |
    ( (Value5 = icase(as_xpr("mark2:") ) ) >> (Value6 =  (+boost::xpressive::set[_d|'.']) ) >> ':' >> (Value7 =  (+boost::xpressive::set[_d]) ) >> optional(as_xpr(",")) ) )
    )
    >> eos;

    boost::trim(string_to_parse);
    smatch what;
    if ( !regex_search(string_to_parse, what, pt)) {
        std::stringstream ss;
        ss << "Unable to parse: " << string_to_parse;
        throw parse::MyException(ss.str());
    }

    std::string Value1_str = what[Value1]; // print them later
    std::string Value2_str = what[Value2]; // print them later
    std::string Value3_str = what[Value3]; // print them later
    std::string Value4_str = what[Value4]; // print them later
    std::string Value5_str = what[Value5]; // print them later
    std::string Value6_str = what[Value6]; // print them later
    std::string Value7_str = what[Value7]; // print them later

string_to_parse = NameX,mark1:192.168.1.100:5555,mark2:192.168.1.101:5556; (passes parsing)


Solution

  • When you match a pattern with nested regexes, you get nested match results. This explains it all.