c++ - Boost regex expression capture -
my goal capture integer using boost::regex_search.
#define boost_regex_match_extra #include <boost\regex.hpp> #include <iostream> int main(int argc, char* argv[]) { std::string tests[4] = { "somestring #222", "somestring #1", "somestring #42", "somestring #-1" }; boost::regex rgx("#(-?[0-9]+)$"); boost::smatch match; for(int i=0;i< 4; ++i) { std::cout << "test " << << std::endl; boost::regex_search(tests[i], match, rgx, boost::match_extra); for(int j=0; j< match.size(); ++j) { std::string match_string; match_string.assign(match[j].first, match[j].second); std::cout << " match " << j << ": " << match_string << std::endl; } } system("pause"); }
i notice each regex search results in 2 matches. first being string matched, , second capture in parenthesis.
test 0 match 0: #222 match 1: 222 test 1 match 0: #1 match 1: 1 test 2 match 0: #42 match 1: 42 test 3 match 0: #-1 match 1: -1
the documentation discourages use of boost_regex_match_extra unless needed. required capture single match within parentheses, or there way?
if want more speed, perhaps boost spirit bring it, or other boost xpressive.
both generate code expression templates. meaning, among other things, if don't "absorb" attribute values, no cost incurred.
boost spirit:
this solution header-only. can made more efficient, here's start:
#include <boost/spirit/include/qi.hpp> namespace qi = boost::spirit::qi; int main() { std::string const tests[] = { "somestring #222", "somestring #1", "somestring #42", "somestring #-1" }; for(auto& input : tests) { int value; auto f(input.begin()), l(input.end()); if (qi::phrase_parse(f, l, // input iterators qi::omit [ *~qi::char_('#') ] >> '#' >> qi::int_, // grammar qi::space, // skipper value)) // output attribute { std::cout << " input '" << input << "' -> " << value << "\n"; } } }
see live on coliru
boost xpressive
#include <boost/xpressive/xpressive_static.hpp> #include <iostream> namespace xp = boost::xpressive; int main() { std::string const tests[] = { "somestring #222", "somestring #1", "somestring #42", "somestring #-1" }; for(auto& input : tests) { static xp::sregex rex = (xp::s1= -*xp::_) >> '#' >> (xp::s2= !xp::as_xpr('-') >> +xp::_d); xp::smatch what; if(xp::regex_match(input, what, rex)) { std::cout << "input '" << what[0] << " -> " << what[2] << '\n'; } } }
see live on coliru too.
i have hunch spirit solution gonna more performant, , close want (because parses general grammar , parses desired data-type directly).
Comments
Post a Comment