|
Boost : |
From: Dave Jenkins (david_at_[hidden])
Date: 2007-11-23 15:25:34
"Jorge Lodos Vigil" <lodos_at_[hidden]> wrote in message
news:ECBF993526E3BC47BD232BDC77D6933706A916F588_at_mercurio.segurmatica.cu...
>
> Dave Jenkins wrote:
>>
>> > Hi
>> > We are using xpressive with a grammar to match certain patterns. In
>> > some cases, we have the need to ignore white spaces.
>> > Using dynamic regexes, this can be achieved with the
>> > ignore_white_space constant.
>> > Is there a way to ignore white spaces using a grammar in xpressive
>> > other than modifying the grammar itself?
>>
>> How about using a filter_iterator to skip spaces. Something
>> like the following program:
>
> Thank you for your help. Unfortunately our grammar definition have spaces,
> we can not remove all of them.
> I'll think more about your idea of modifying the way to traverse the
> string, perhaps we may do some sort of preprocessing.
Oh, I see. How about something like this? It allows you to selectively
skip spaces for parts of your regex.
#include <iostream>
#include <string>
#include <boost/iterator/filter_iterator.hpp>
#include <boost/range/iterator_range.hpp>
#include <boost/xpressive/xpressive_static.hpp>
#include <boost/xpressive/regex_actions.hpp>
#include <boost/xpressive/proto/proto_typeof.hpp>
static bool skip_spaces = false;
struct not_space {
inline bool operator()(char ch) const
{ return ' ' != ch || !skip_spaces; }
static bool disable(std::string const & s)
{ skip_spaces = false; return true; }
static bool enable(std::string const & s)
{ skip_spaces = true; return true; }
};
typedef boost::filter_iterator<not_space,
std::string::const_iterator> Iter_Skip;
boost::iterator_range<Iter_Skip> make_range (std::string const& s)
{
return boost::make_iterator_range(
boost::make_filter_iterator<not_space>(s.begin(), s.end()),
boost::make_filter_iterator<not_space>(s.end(), s.end())
);
}
int main()
{
using namespace boost::xpressive;
std::string s = "a ab bc c";
BOOST_PROTO_AUTO( skip_spaces,
nil[check(¬_space::enable)]
);
BOOST_PROTO_AUTO( normal,
nil[check(¬_space::disable)]
);
typedef basic_regex<Iter_Skip> regex_skip;
regex_skip rx =
normal >> as_xpr("a a") >>
skip_spaces >> "bb" >>
normal >> "c c";
match_results<Iter_Skip> what;
if(!regex_match(make_range(s), what, rx))
std::cout << "not found\n";
else
std::cout << "found\n";
return 0;
}
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk