8

我在boost::regex_replace. 我可以调用它的一个参数版本,但不能调用两个参数:

e = "(^|>)([^<>]+)";
h_str = regex_replace(h_str, e, repl_quot, boost::match_default);

其中repl_quot定义为

std::string const &repl_quot(boost::smatch const &what) {
    boost::regex e("\"");
    std::string  repl("&#34;");
    static std::string;
    str = regex_replace(what[0].str(), e, repl, boost::match_default);
    return str;
}

以上工作,但我真的不想使用那个静态变量,所以我尝试了我认为是可接受的两个参数替代版本:

std::string const &repl_quot2(boost::smatch const &what, std::string &out) {
    boost::regex e("\"");
    std::string  repl("&#34;");
    out = regex_replace(what[0].str(), e, repl, boost::match_default);
    return out;
}

但是 regex_replace 不会接受这个(一个复杂的编译器错误)。我正在尝试根据Boost::Regex文档中的以下内容使用两个参数版本:

模板 basic_string regex_replace(const basic_string& s, const basic_regex& e, Formatter fmt, match_flag_type flags = match_default);

要求类型 Formatter 必须是...一个从函数调用计算替换字符串的一元、二元或三元仿函数:要么是 fmt(what),它必须返回一个 char_type 的容器以用作替换文本,要么是 fmt (what, out) 或 fmt(what, out, flags),两者都将替换文本写入 *out,然后返回新的 OutputIterator 位置。在每种情况下,代表找到的匹配项的 match_results 对象是什么。

已经多次请求编译器错误消息,所以这里是(小心你要求的):

c:\boost\boost\regex\v4\regex_format.hpp 在成员函数`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 从 `OutputIterator boost::match_results::format(OutputIterator, Functor, boost::regex_constants::match_flag_type, const RegexT&) 实例化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 从`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 从`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 ::细绳&)]'

327 C:\Dev-Cpp\Examples\wordrad\xhtml_open.cpp 从这里实例化

第1064begin' in章boost::regex_traits_wrapper > > >*)this)->boost::re_detail::format_functor_container, std::allocator > >, std::allocator, std::allocator > > > > >, boost::regex_traits_wrapper > > > ::func',它是非类类型 `const std::string&(* const)(const boost::smatch&, std::string&)'

第1064end' in章boost::regex_traits_wrapper > > >*)this)->boost::re_detail::format_functor_container, std::allocator > >, std::allocator, std::allocator > > > > >, boost::regex_traits_wrapper > > > ::func',它是非类类型 `const std::string&(* const)(const boost::smatch&, std::string&)'

4

1 回答 1

1

好的,这就是我必须编写 repl_quot2 的方式:

struct formatter
{       
  template<typename Out>
  Out operator()(boost::smatch const &what, Out out) const {
    boost::regex e("\"");    
    std::string  repl("&#34;");
    std::string str
      = regex_replace(what[0].str(), e, repl, boost::match_default);
    out = std::copy(str.begin(), str.end(), out);
    return out;
  }

};

然后从 regex_replace 调用它时:

  e = "(^|>)[^<>]+";
  formatter repl_quot2;
  h_str = regex_replace(h_str, e, repl_quot2, boost::match_default);

这对应于http://boost-sandbox.sourceforge.net/libs/xpressive/doc/html/boost_xpressive/user_s_guide/string_substitutions.html上的文档。

目前让我感到困惑的是,如果调用两个参数版本,它需要一个仿函数(一个带有 () 运算符的类)而不是一个函数,但对于一个参数版本不需要仿函数(OP 中的 repl_quot )。无论如何,还没有让新的两个 parm 版本作为直接函数工作。但主要问题是out我必须将其作为模板参数传递和返回,如图所示,而不是像在 OP 中那样使其成为 std::string。它应该是一个 OutputIterator - 仍然不知道那实际上是什么。

顺便说一句,这个正则表达式所做的就是用 html 实体版本替换双引号,\" 在 html 中的任何文本中都不是标签的一部分。

另外,我想替换原始函数 repl_quot 的原因是我必须将返回值存储在 repl_quot 中的静态局部变量中。只返回一个普通的局部变量是行不通的,因为它甚至可以在使用之前被释放(并导致崩溃)。repl_quot 正在工作 - 我的静态问题是它不是线程安全的,并且不知道 Boost::RegEx 是否是多线程的。我想我将它编译为多线程,但静态 var 似乎没有引起问题。但是使用 repl_quot2 我将返回值写入输出参数。

于 2011-01-30T12:29:12.453 回答