boost::xpressive : Get thousand separator as double

Hi! I'm playing a bit with boost::xpressive and have no clue how to get a 100,000 (comma as separator) to a double as 1000000.00 or 250,000.10 as a double 250000.10 or 12,00 as double 12.00 or 1,200,500.00 as double 1200500.00. I'm working with xpressive since a day. What's the regex for that? And how can i use it in xpressive-grammar as a nested regex? Example subject: "I payed 100,200.50 Dollar" Example Regex on subject: 'I payed' >> (s1=getdoubleregex) >> ' Dollar' Is it possible to do it like that? Set return-value/type in a regex? Thank you very much!

On 9/8/2011 5:09 PM, Jens Saathoff wrote:
Hi!
I'm playing a bit with boost::xpressive and have no clue how to get a 100,000 (comma as separator) to a double as 1000000.00 or 250,000.10 as a double 250000.10 or 12,00 as double 12.00 or 1,200,500.00 as double 1200500.00. I'm working with xpressive since a day. What's the regex for that?
And how can i use it in xpressive-grammar as a nested regex?
Example subject: "I payed 100,200.50 Dollar"
Example Regex on subject: 'I payed' >> (s1=getdoubleregex) >> ' Dollar'
Is it possible to do it like that? Set return-value/type in a regex?
Try something like the following: #include <string> #include <iostream> #include <iomanip> #include <boost/xpressive/xpressive_static.hpp> #include <boost/xpressive/regex_actions.hpp> namespace xp = boost::xpressive; int main() { using namespace xp; placeholder<double> result; sregex double_ = ~after(_d) >> // a number with no group separators, and either a period or comma // for fraction separator (+_d)[result = as<double>(_)] >> !((set=',','.') >> (_d >> _d)[result += as<int>(_)/100.0]) >> ~before(set[_d|','|'.']) // A number with optional group separators | repeat<1,3>(_d)[result = as<int>(_)] >> ( // ... with comma group separators and period fraction separator *(',' >> repeat<3>(_d)[result *= 1000, result += as<int>(_)]) >> !('.' >> (_d >> _d)[result += as<int>(_)/100.0]) >> ~before(set[_d|','|'.']) // ... with period group separators and comma fraction separator | *('.' >> repeat<3>(_d)[result *= 1000, result += as<int>(_)]) >> !(',' >> (_d >> _d)[result += as<int>(_)/100.0]) >> ~before(set[_d|','|'.']) ); std::string str; double d = 0.0; smatch what; what.let(result = d); std::cout << std::fixed << std::setprecision(2); while (std::getline(std::cin, str)) { if (regex_search(str, what, double_)) { std::cout << "Double = " << d << '\n'; } else { std::cout << "No match\n"; } } } -- Eric Niebler BoostPro Computing http://www.boostpro.com

Perfect! That works! I will compare it with my thousand-sep rule/grammar in boost::spirit, a little benchmark to find out which one is faster. Do have experiences/results with boost::spirit vs. boost::xpressive? Thank you very much. Have a nice weekend. 2011/9/9 Eric Niebler <eric@boostpro.com>
#include <string> #include <iostream> #include <iomanip> #include <boost/xpressive/xpressive_static.hpp> #include <boost/xpressive/regex_actions.hpp> namespace xp = boost::xpressive;
int main() { using namespace xp; placeholder<double> result; sregex double_ = ~after(_d) >> // a number with no group separators, and either a period or comma // for fraction separator (+_d)[result = as<double>(_)] >> !((set=',','.') >> (_d >> _d)[result += as<int>(_)/100.0]) >> ~before(set[_d|','|'.']) // A number with optional group separators | repeat<1,3>(_d)[result = as<int>(_)] >> ( // ... with comma group separators and period fraction separator *(',' >> repeat<3>(_d)[result *= 1000, result += as<int>(_)]) >> !('.' >> (_d >> _d)[result += as<int>(_)/100.0]) >> ~before(set[_d|','|'.']) // ... with period group separators and comma fraction separator | *('.' >> repeat<3>(_d)[result *= 1000, result += as<int>(_)]) >> !(',' >> (_d >> _d)[result += as<int>(_)/100.0]) >> ~before(set[_d|','|'.']) );
std::string str; double d = 0.0; smatch what; what.let(result = d); std::cout << std::fixed << std::setprecision(2); while (std::getline(std::cin, str)) { if (regex_search(str, what, double_)) { std::cout << "Double = " << d << '\n'; } else { std::cout << "No match\n"; } } }

If performance matters, you might want to avoid xpressive::as. It's just a thin wrapper over boost::lexical_cast, which may(?) do dynamic allocation while performing conversion. Try this, which uses a wrapper over std::atoi instead. (It's a bit sneaky in that it uses the fact that characters in a string are guaranteed contiguous, and that atoi stops parsing on the first non-digit.) Disclaimer: this code is not well-tested. struct asint_ : std::unary_function<xp::ssub_match, int> { int operator()(xp::ssub_match const &s) const { return (int)std::atoi(&*s.first); } }; xp::function<asint_>::type const asint = {}; int main() { using namespace xp; placeholder<double> result; sregex double_ = ~after(_d) >> // a number with no group separators, and either a period or comma // for fraction separator (+_d)[result = asint(_)] >> !((set=',','.') >> (_d >> _d)[result += asint(_)/100.0]) >> ~before(set[_d|','|'.']) // A number with optional group separators | repeat<1,3>(_d)[result = asint(_)] >> ( // ... with comma group separators and period fraction separator *(',' >> repeat<3>(_d)[result *= 1000, result += asint(_)]) >> !('.' >> (_d >> _d)[result += asint(_)/100.0]) >> ~before(set[_d|','|'.']) // ... with period group separators and comma fraction separator | *('.' >> repeat<3>(_d)[result *= 1000, result += asint(_)]) >> !(',' >> (_d >> _d)[result += asint(_)/100.0]) >> ~before(set[_d|','|'.']) ); std::string str; double d = 0.0; smatch what; what.let(result = d); std::cout << std::fixed << std::setprecision(2); while (std::getline(std::cin, str)) { if (regex_search(str, what, double_)) { std::cout << "Double = " << d << '\n'; } else { std::cout << "No match\n"; } } } On 9/9/2011 5:26 AM, Jens Saathoff wrote:
Perfect! That works!
I will compare it with my thousand-sep rule/grammar in boost::spirit, a little benchmark to find out which one is faster. Do have experiences/results with boost::spirit vs. boost::xpressive?
Thank you very much. Have a nice weekend.
2011/9/9 Eric Niebler <eric@boostpro.com <mailto:eric@boostpro.com>>
#include <string> #include <iostream> #include <iomanip> #include <boost/xpressive/xpressive_static.hpp> #include <boost/xpressive/regex_actions.hpp> namespace xp = boost::xpressive;
int main() { using namespace xp; placeholder<double> result; sregex double_ = ~after(_d) >> // a number with no group separators, and either a period or comma // for fraction separator (+_d)[result = as<double>(_)] >> !((set=',','.') >> (_d >> _d)[result += as<int>(_)/100.0]) >> ~before(set[_d|','|'.']) // A number with optional group separators | repeat<1,3>(_d)[result = as<int>(_)] >> ( // ... with comma group separators and period fraction separator *(',' >> repeat<3>(_d)[result *= 1000, result += as<int>(_)]) >> !('.' >> (_d >> _d)[result += as<int>(_)/100.0]) >> ~before(set[_d|','|'.']) // ... with period group separators and comma fraction separator | *('.' >> repeat<3>(_d)[result *= 1000, result += as<int>(_)]) >> !(',' >> (_d >> _d)[result += as<int>(_)/100.0]) >> ~before(set[_d|','|'.']) );
std::string str; double d = 0.0; smatch what; what.let(result = d); std::cout << std::fixed << std::setprecision(2); while (std::getline(std::cin, str)) { if (regex_search(str, what, double_)) { std::cout << "Double = " << d << '\n'; } else { std::cout << "No match\n"; } } }
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
-- Eric Niebler BoostPro Computing http://www.boostpro.com

Hi! And again...thank you very much for your help. Very kind of you. There's one question left: What does smatch::let? In the doc there's a short comment on it: TODO document me Would you please explain it in short? Thank you! 2011/9/9 Eric Niebler <eric@boostpro.com>
If performance matters, you might want to avoid xpressive::as. It's just a thin wrapper over boost::lexical_cast, which may(?) do dynamic allocation while performing conversion. Try this, which uses a wrapper over std::atoi instead. (It's a bit sneaky in that it uses the fact that characters in a string are guaranteed contiguous, and that atoi stops parsing on the first non-digit.)
Disclaimer: this code is not well-tested.
struct asint_ : std::unary_function<xp::ssub_match, int> { int operator()(xp::ssub_match const &s) const { return (int)std::atoi(&*s.first); } };
xp::function<asint_>::type const asint = {};
int main() { using namespace xp; placeholder<double> result; sregex double_ = ~after(_d) >> // a number with no group separators, and either a period or comma // for fraction separator (+_d)[result = asint(_)] >> !((set=',','.') >> (_d >> _d)[result += asint(_)/100.0]) >> ~before(set[_d|','|'.']) // A number with optional group separators | repeat<1,3>(_d)[result = asint(_)] >> ( // ... with comma group separators and period fraction separator *(',' >> repeat<3>(_d)[result *= 1000, result += asint(_)]) >> !('.' >> (_d >> _d)[result += asint(_)/100.0]) >> ~before(set[_d|','|'.']) // ... with period group separators and comma fraction separator | *('.' >> repeat<3>(_d)[result *= 1000, result += asint(_)]) >> !(',' >> (_d >> _d)[result += asint(_)/100.0]) >> ~before(set[_d|','|'.']) );
std::string str; double d = 0.0; smatch what; what.let(result = d); std::cout << std::fixed << std::setprecision(2); while (std::getline(std::cin, str)) { if (regex_search(str, what, double_)) { std::cout << "Double = " << d << '\n'; } else { std::cout << "No match\n"; } } }
On 9/9/2011 5:26 AM, Jens Saathoff wrote:
Perfect! That works!
I will compare it with my thousand-sep rule/grammar in boost::spirit, a little benchmark to find out which one is faster. Do have experiences/results with boost::spirit vs. boost::xpressive?
Thank you very much. Have a nice weekend.
2011/9/9 Eric Niebler <eric@boostpro.com <mailto:eric@boostpro.com>>
#include <string> #include <iostream> #include <iomanip> #include <boost/xpressive/xpressive_static.hpp> #include <boost/xpressive/regex_actions.hpp> namespace xp = boost::xpressive;
int main() { using namespace xp; placeholder<double> result; sregex double_ = ~after(_d) >> // a number with no group separators, and either a period or comma // for fraction separator (+_d)[result = as<double>(_)] >> !((set=',','.') >> (_d >> _d)[result += as<int>(_)/100.0])
~before(set[_d|','|'.']) // A number with optional group separators | repeat<1,3>(_d)[result = as<int>(_)] >> ( // ... with comma group separators and period fraction separator *(',' >> repeat<3>(_d)[result *= 1000, result += as<int>(_)]) >> !('.' >> (_d >> _d)[result += as<int>(_)/100.0]) >> ~before(set[_d|','|'.']) // ... with period group separators and comma fraction separator | *('.' >> repeat<3>(_d)[result *= 1000, result += as<int>(_)]) >> !(',' >> (_d >> _d)[result += as<int>(_)/100.0]) >> ~before(set[_d|','|'.']) );
std::string str; double d = 0.0; smatch what; what.let(result = d); std::cout << std::fixed << std::setprecision(2); while (std::getline(std::cin, str)) { if (regex_search(str, what, double_)) { std::cout << "Double = " << d << '\n'; } else { std::cout << "No match\n"; } } }
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
-- Eric Niebler BoostPro Computing http://www.boostpro.com _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users

On 9/9/2011 6:30 PM, Jens Saathoff wrote:
There's one question left: What does smatch::let? In the doc there's a short comment on it: TODO document me
Would you please explain it in short?
Ah, the reference section needs updating, but this is described in the users' guide: http://www.boost.org/doc/libs/1_47_0/doc/html/xpressive/user_s_guide.html#bo... HTH, -- Eric Niebler BoostPro Computing http://www.boostpro.com

Thank you very much! Is it possible to mix static and dynamic xpressive as nested xpressions like: staticregex = double_; (the code you provided) dynregex.compile("i paid:" >> staticregex); That's just a very short example, but i think you understand what i mean here. Thankx a lot! 2011/9/10 Eric Niebler <eric@boostpro.com>
On 9/9/2011 6:30 PM, Jens Saathoff wrote:
There's one question left: What does smatch::let? In the doc there's a short comment on it: TODO document me
Would you please explain it in short?
Ah, the reference section needs updating, but this is described in the users' guide:
http://www.boost.org/doc/libs/1_47_0/doc/html/xpressive/user_s_guide.html#bo...
HTH,
-- Eric Niebler BoostPro Computing http://www.boostpro.com _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users

(Please don't top-post) On 9/13/2011 6:54 PM, Jens Saathoff wrote:
Is it possible to mix static and dynamic xpressive as nested xpressions like:
staticregex = double_; (the code you provided) dynregex.compile("i paid:" >> staticregex);
That's just a very short example, but i think you understand what i mean here.
Yes, dynamic regexes can embedded in static regexes, and static regexes can be embedded in dynamic regexes via named regexes. It's all described in the users' guide. -- Eric Niebler BoostPro Computing http://www.boostpro.com

Yes, you are right. I overlooked it and used the wrong search term. Thanks 2011/9/14 Eric Niebler <eric@boostpro.com>
(Please don't top-post)
On 9/13/2011 6:54 PM, Jens Saathoff wrote:
Is it possible to mix static and dynamic xpressive as nested xpressions like:
staticregex = double_; (the code you provided) dynregex.compile("i paid:" >> staticregex);
That's just a very short example, but i think you understand what i mean here.
Yes, dynamic regexes can embedded in static regexes, and static regexes can be embedded in dynamic regexes via named regexes. It's all described in the users' guide.
-- Eric Niebler BoostPro Computing http://www.boostpro.com _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
participants (2)
-
Eric Niebler
-
Jens Saathoff