Проблемы с функцией двухпараметрического формата в boost :: regex_replace - PullRequest
7 голосов
/ 30 января 2011

У меня проблемы с функцией форматирования в 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, flags_flag_type flags = match_default);

Требуется тип Formatter должен быть или ... унарный, бинарный или троичный функтор, который вычисляет строку замены из вызов функции: либо fmt (что), который должен вернуть контейнер char_type использоваться в качестве заменяющего текста, или либо fmt (что, out) или fmt (что, флаги), оба из которых пишут текст замены на * 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>>, контейнер = 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 [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) match с 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 :: строка & (*) (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 :: 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 &)'

1 Ответ

1 голос
/ 30 января 2011

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

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

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

...