【问题标题】:Problems with the two parameter format function in boost::regex_replaceboost::regex_replace中两个参数格式函数的问题
【发布时间】:2011-06-17 23:28:24
【问题描述】:

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& s, const basic_regex& e, 格式化程序 fmt, match_flag_type 标志 = 匹配默认);

要求 Formatter 类型必须是 要么 ... 一元,二元或三元函子, 从 a 计算替换字符串 函数调用:要么 fmt(what) 哪个 必须返回一个 char_type 的容器 用作替换文本,或 fmt(what, out) 或 fmt(what, 出,标志),这两个写 替换文本到 *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 >, 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&) 实例化 [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 从 `OutputIterator boost::regex_replace(OutputIterator, BidirectionalIterator, BidirectionalIterator, const boost::basic_regex&, Formatter, boost::regex_constants::match_flag_type) 实例化 [使用 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 >&, 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 从这里实例化

1064 c:\boost\boost\regex\v4\regex_format.hpp 请求成员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',属于非类类型`const std::string&(* const)(const boost::smatch&, std::string&)'

1064 c:\boost\boost\regex\v4\regex_format.hpp 请求成员 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',属于非类类型`const std::string&(* const)(const boost::smatch&, std::string&)'

【问题讨论】:

  • 您应该发布您遇到的错误。
  • 它长得离谱。我预测你不会对它做出正面或反面。它的模板相关什么的。问题在于 regex-replace 期望作为 fmt 参数的签名,与模板或其他内容有关。错误信息无法解读。
  • 1064 c:\boost\boost\regex\v4\regex_format.hpp 请求成员end' in ((boost::re_detail::format_functor_container)( const boost::smatch&, std::string&), boost::match_results<:__normal_iterator char>, std::basic_string, std::allocator > >, std::allocator<:sub_match char std::basic_string std::char_traits>, std::allocator > > > > > , boost::regex_traits_wrapper<:regex_traits boost::cpp_regex_traits> > > >*)this)->boost::re_detail::format_fu...
  • 我认为static std::string; 行中缺少某些内容,或者必须删除那里的分号。而且我认为str 在该示例中不需要是静态的。您能否在问题中发布整个错误消息,因为这些 cmets 的长度不足以提供完整的错误消息。
  • Wimmel - 带有静态 std::string 的版本是有效的版本。甚至其他版本的 repl_quot2 也可以实际编译。如果我将 repl_quot2 作为参数传递给 regex_replace(而不是 repl_quot),则会发生编译器错误,因为 regex_quot2 的参数和返回值不符合 regex_replace 的预期,我不知道它想要什么。您可以从文档摘录中看到,一个两个或三个参数的函数是可以接受的。它还说,使用两个参数,您将替换文本写入 *out 并返回新的“OutputIterator”位置...

标签: c++ regex templates boost-regex


【解决方案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 的文档。

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

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

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

【讨论】:

    猜你喜欢
    • 2011-09-24
    • 1970-01-01
    • 2016-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多