Проблемы с функцией двухпараметрического формата в boost :: regex_replace

У меня проблемы с функцией форматирования в 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 &) [с 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 &) const [с 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_tetype = 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) [с traits = boost :: regex_traits>, charT = char, Formatter = const std :: string & (*) (const boost :: smatch &, std ::нить&)]'

327 C: \ Dev-Cpp \ Примеры \ wordrad \ xhtml_open.cpp, созданный отсюда

1064 c: \ boost \ boost \ regex \ v4 \ regex_format.hpp запрос для члена _7 _ ((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 запрос для члена _8 _ ((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 &)'


person Mark    schedule 30.01.2011    source источник
comment
Вы должны опубликовать сообщение об ошибке.   -  person Eric Fortin    schedule 30.01.2011
comment
Это абсурдно долго. Я предсказываю, что вы не будете разбираться в этом. Это связано с шаблоном или чем-то в этом роде. Проблема в том, что regex-replace ожидает в качестве сигнатуры для параметра fmt, привязки к шаблонам или чему-то еще. Сообщение об ошибке не поддается расшифровке.   -  person Mark    schedule 30.01.2011
comment
1064 c: \ boost \ boost \ regex \ v4 \ regex_format.hpp запрос для члена _1 _ ((boost :: re_detail :: format_functor_container ‹const std :: string & () (const boost :: smatch &, std :: string & ), boost :: match_results ‹__ gnu_cxx :: __ normal_iterator‹ const char, std :: basic_string ‹char, std :: char_traits ‹char›, std :: allocator ‹char›› ›, std :: allocator‹ boost :: sub_match ‹__ gnu_cxx :: __ normal_iterator‹ const char *, std :: basic_string ‹char, std :: char_traits ‹char›, std :: allocator ‹char›› ›› ››, boost :: regex_traits_wrapper ‹boost :: regex_traits ‹Char, boost :: cpp_regex_traits ‹char›› ›› *) this) - ›boost :: re_detail :: format_fu ...   -  person Mark    schedule 30.01.2011
comment
Думаю, в строке static std::string; чего-то не хватает, либо точку с запятой там нужно убрать. И я не думаю, что str должен быть статичным в этом примере. Можете ли вы опубликовать все сообщение об ошибке в вопросе, так как этих комментариев недостаточно для полного сообщения об ошибке.   -  person wimh    schedule 30.01.2011
comment
Wimmel - версия со статическим std :: string является той, которая работает. Даже другая версия repl_quot2 компилируется. Ошибка компилятора возникает, если я передаю repl_quot2 в качестве параметра в regex_replace (вместо repl_quot), потому что параметры и возвращаемое значение regex_quot2 не соответствуют тому, что ожидает regex_replace, и я не знаю, чего он хочет. Из выдержки из документации видно, что допустима функция одного, двух или трех параметров. В нем также говорится, что с двумя параметрами вы пишете заменяющий текст в * out и возвращаете новый OutputIterator pos ...   -  person Mark    schedule 30.01.2011
comment
Честно говоря, я не знаю, что означает OutputIterator, так что это часть проблемы. Более подробный пример можно найти в boost-sandbox .sourceforge.net / libs / xpressive / doc / html /, но это касается Boost :: xpressive, а не Boost :: regex, но предполагается, что они тесно связаны. Но мой код следует тому, что описано на этой странице для Boost :: xpressive, потому что это единственный найденный мной документ с подробными примерами.   -  person Mark    schedule 30.01.2011


Ответы (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, который мне пришлось передать и вернуть в качестве параметра шаблона, как показано, в отличие от того, чтобы сделать его std :: string, как в OP. Предполагается, что это OutputIterator - до сих пор не знаю, что это на самом деле.

Между прочим, все это регулярное выражение заменяет двойные кавычки версией сущности html \ "в любом тексте в html, не являющемся частью тега.

Кроме того, причина, по которой я хотел заменить свою исходную функцию repl_quot, заключается в том, что мне пришлось сохранить возвращаемое значение в статической локальной переменной в repl_quot. Невозможно просто вернуть обычную локальную переменную, потому что она может быть освобождена до того, как ее можно будет использовать (и это приведет к сбою). repl_quot работал - моя проблема со статикой в ​​том, что она не является потокобезопасной, и я не знал, является ли Boost :: RegEx многопоточным. Думаю, я скомпилировал его как многопоточность, но статическая переменная, похоже, не вызвала проблем. Но с помощью repl_quot2 я записываю возвращаемое значение в выходной параметр.

person Mark    schedule 30.01.2011