Boost logo

Boost Users :

Subject: Re: [Boost-users] boost::xpressive : Get thousand separator as double
From: Eric Niebler (eric_at_[hidden])
Date: 2011-09-08 22:07:25


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

Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net