Boost logo

Boost :

From: Eric Niebler (eric_at_[hidden])
Date: 2008-03-14 13:42:57


Robert Dailey wrote:
> An example of a string that I'll be searching is below:
>
> "This string $(variable1) has localized $(var2) text interleaved for no
> $(reason)"
>
> In the string above, we have 3 variables. Each variable will reference a
> string in a localization table, which will then be used to replace the
> variable itself.

It's not be hard to build such a thing using using regex_iterator.
Here's some code to get you going...

#include <map>
#include <iostream>
#include <boost/xpressive/xpressive.hpp>
using namespace boost;

template<typename OutIter, typename OtherBidiIter, typename BidiIter,
typename Format>
inline OutIter regex_grep(
     OutIter out
   , OtherBidiIter begin_
   , OtherBidiIter end_
   , xpressive::basic_regex<BidiIter> const &re
   , Format format
   , xpressive::regex_constants::match_flag_type flags =
xpressive::regex_constants::match_default
)
{
     BidiIter begin = begin_, end = end_;
     xpressive::regex_iterator<BidiIter> it1(begin, end, re, flags), it2;
     bool yes_copy = !(flags & xpressive::regex_constants::format_no_copy);

     for(; it1 != it2; ++it1)
     {
         if(yes_copy)
             out = std::copy(begin, (*it1)[0].first, out);
         out = format(*it1, out);
         begin = (*it1)[0].second;
     }

     if(yes_copy)
         out = std::copy(begin, end, out);
     return out;
}

std::map<std::string, std::string> replacements;

struct format
{
     template<typename BidiIter, typename OutIter>
     OutIter operator()(xpressive::match_results<BidiIter> const &what,
OutIter out) const
     {
         std::map<std::string, std::string>::const_iterator where =
replacements.find(what[1].str());
         if(where != replacements.end())
             out = std::copy((*where).second.begin(),
(*where).second.end(), out);
         return out;
     }
};

int main()
{
     replacements["X"] = "this";
     replacements["Y"] = "that";

     std::string input("\"$(X)\" has the value \"$(Y)\""), output;
     xpressive::sregex rx =
xpressive::sregex::compile("\\$\\(([^\\)]+)\\)");

     regex_grep(std::back_inserter(output), input.begin(), input.end(),
rx, format());

     std::cout << output << std::endl;
     return 0;
}

HTH,

-- 
Eric Niebler
Boost Consulting
www.boost-consulting.com

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk