I am having problems with the format function in boost::regex_replace
. I can call the one parameter version of it, but not the two parameter:
e = "(^|>)([^<>]+)";
h_str = regex_replace(h_str, e, repl_quot, boost::match_default);
Where repl_quot
is defined as
std::string const &repl_quot(boost::smatch const &what) {
boost::regex e("\"");
std::string repl(""");
static std::string;
str = regex_replace(what[0].str(), e, repl, boost::match_default);
return str;
}
The above works, but I don't really want to use that static variable, so I tried what I thought was an acceptable two parameter alternate version:
std::string const &repl_quot2(boost::smatch const &what, std::string &out) {
boost::regex e("\"");
std::string repl(""");
out = regex_replace(what[0].str(), e, repl, boost::match_default);
return out;
}
But regex_replace won't accept this (a convoluted compiler error). I am trying to use the two parameter version based on the following from the Boost::Regex
documentation:
template basic_string regex_replace(const basic_string& s, const basic_regex& e, Formatter fmt, match_flag_type flags = match_default);
Requires The type Formatter must be either ... a unary, binary or ternary functor that computes the replacement string from a function call: either fmt(what) which must return a container of char_type's to be used as the replacement text, or either fmt(what, out) or fmt(what, out, flags), both of which write the replacement text to *out, and then return the new OutputIterator position. In each case what is the match_results object that represents the match found.
There have been repeated requests for the compiler error message, so here it is (be careful what you ask for):
c:\boost\boost\regex\v4\regex_format.hpp In member function `OutputIter boost::re_detail::format_functor_container::operator()(const Match&, OutputIter, boost::regex_constants::match_flag_type, const Traits&) [with OutputIter = boost::re_detail::string_out_iterator, std::allocator > >, Container = const std::string&(*)(const boost::smatch&, std::string&), Match = boost::match_results<__gnu_cxx::__normal_iterator, std::allocator > >, std::allocator, std::allocator > > > > >, Traits = boost::regex_traits_wrapper > >]':
356 c:\boost\boost\regex\v4\match_results.hpp instantiated from `OutputIterator boost::match_results::format(OutputIterator, Functor, boost::regex_constants::match_flag_type, const RegexT&) const [with OutputIterator = boost::re_detail::string_out_iterator, std::allocator > >, Functor = const std::string&(*)(const boost::smatch&, std::string&), RegexT = boost::basic_regex > >, BidiIterator = __gnu_cxx::__normal_iterator, std::allocator > >, Allocator = std::allocator, std::allocator > > > >]'
60 c:\boost\boost\regex\v4\regex_replace.hpp instantiated from `OutputIterator boost::regex_replace(OutputIterator, BidirectionalIterator, BidirectionalIterator, const boost::basic_regex&, Formatter, boost::regex_constants::match_flag_type) [with OutputIterator = boost::re_detail::string_out_iterator, std::allocator > >, BidirectionalIterator = __gnu_cxx::__normal_iterator, std::allocator > >, traits = boost::regex_traits >, charT = char, Formatter = const std::string&(*)(const boost::smatch&, std::string&)]'
80 c:\boost\boost\regex\v4\regex_replace.hpp instantiated from `std::basic_string, std::allocator<_T2> > boost::regex_replace(const std::basic_string, std::allocator<_T2> >&, const boost::basic_regex&, Formatter, boost::regex_constants::match_flag_type) [with traits = boost::regex_traits >, charT = char, Formatter = const std::string&(*)(const boost::smatch&, std::string&)]'
327 C:\Dev-Cpp\Examples\wordrad\xhtml_open.cpp instantiated from here
1064 c:\boost\boost\regex\v4\regex_format.hpp request for member
begin' in
((boost::re_detail::format_functor_container, std::allocator > >, std::allocator, std::allocator > > > > >, boost::regex_traits_wrapper > > >*)this)->boost::re_detail::format_functor_container, std::allocator > >, std::allocator, std::allocator > > > > >, boost::regex_traits_wrapper > > >::func', which is of non-class type `const std::string&(* const)(const boost::smatch&, std::string&)'1064 c:\boost\boost\regex\v4\regex_format.hpp request for member
end' in
((boost::re_detail::format_functor_container, std::allocator > >, std::allocator, std::allocator > > > > >, boost::regex_traits_wrapper > > >*)this)->boost::re_detail::format_functor_container, std::allocator > >, std::allocator, std::allocator > > > > >, boost::regex_traits_wrapper > > >::func', which is of non-class type `const std::string&(* const)(const boost::smatch&, std::string&)'
OK here's how I had to write repl_quot2:
struct formatter
{
template<typename Out>
Out operator()(boost::smatch const &what, Out out) const {
boost::regex e("\"");
std::string repl(""");
std::string str
= regex_replace(what[0].str(), e, repl, boost::match_default);
out = std::copy(str.begin(), str.end(), out);
return out;
}
};
And then when invoking it from regex_replace:
e = "(^|>)[^<>]+";
formatter repl_quot2;
h_str = regex_replace(h_str, e, repl_quot2, boost::match_default);
This corresponds to the documentation at http://boost-sandbox.sourceforge.net/libs/xpressive/doc/html/boost_xpressive/user_s_guide/string_substitutions.html.
What puzzles me at the moment is that it requires a functor (a class with the () operator) as opposed to a function if the two parameter version is called, but did not require a functor for the one parameter versions (repl_quot in the OP). Anyway, haven't gotten the new two parm version to work as a straight function. But the main problem was out
which I had to pass and return as a template parameter as shown, as opposed to making it std::string as in the OP. Its supposed to be an OutputIterator -still don't know what that is actually.
Incidentally, all this regex does is replace double quotes with the html entity version, \" in any text in html not part of a tag.
Also, the reason I wanted to replace my original function repl_quot is that I had to store the return value in a static local variable in repl_quot. It doesn't work to just return a normal local variable, because it can be deallocated before it can even be used (and caused crashes). repl_quot was working - my problem with the static is that it isn't thread safe, and didn't know if Boost::RegEx was multithreading. I think I compiled it as multithreading, but the static var didn't seem to cause problems. But with repl_quot2 I write the return value to an output parameter.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With