Как использовать boost regex_replace с лямбда-функцией?

Я пытаюсь использовать лямбда-функцию для вызова boost::regex_replace на std::string тип. Мне не повезло, что все типы были правильными.

typedef boost::basic_regex<char> regex;
typedef boost::match_results<char> smatch;

    std::string text = "some {test} data";
    regex re( "\\{([^\\}]*)\\}" );
    text  = boost::regex_replace( text, re, [&](smatch const & what) {
        return what.str();
    });

я использую typedef вместо стандартных имен, так как у меня есть несколько мест, которые используют тип символов typedef'd/templated вместо фиксированного типа.

В этом коде я получаю эту ошибку: /usr/include/boost/regex/v4/match_results.hpp:68:77: error: no type named 'difference_type' in 'struct boost::re_detail::regex_iterator_traits<char>' BidiIterator>::difference_type difference_type;

3 ответа

Если у вас есть компилятор, совместимый с C++11, вам не нужны ни Boost, ни лямбды.

Для достижения той же цели вы можете просто использовать std::regex:

#include <iostream>
#include <regex>

int main()
{
  std::string text = "some {test} data {asdf} more";
  std::regex re("\\{([^\\}]*)\\}");
  std::string out;
  std::string::const_iterator it = text.cbegin(), end = text.cend();
  for (std::smatch match; std::regex_search(it, end, match, re); it = match[0].second)
  {
    out += match.prefix();
    out += match.str(); // replace here
  }
  out.append(it, end);
  std::cout << out << std::endl;
}

Конечно, для простой замены текста вы можете просто использовать std::regex_replace() но он не может принимать функтор, только строки статического формата, опционально с групповыми заполнителями:

  std::string text = "some {test} data {asdf} more";
  std::regex re("\\{([^\\}]*)\\}");
  std::string out = std::regex_replace(text, re, "<$1>");

Как указано на справочной странице match_results, первый параметр типа boost::match_results тип BidirectionalIterator; так, например, стандартный typedef boost::smatch является match_results<std::string::const_iterator>,

Чтобы исправить код, вам нужно исправить smatch typedef и либо удалите ссылку на лямбда-параметр what или сделайте это const-ссылкой:

typedef boost::basic_regex<char> regex;
typedef boost::match_results<std::string::const_iterator> smatch;

std::string text = "some {test} data";
regex re("\\{([^\\}]*)\\}");
text = boost::regex_replace(text, re, [] (const smatch& what) {
    return what.str();
});

Что-то не так с smatch тип. Я не смог найти рабочий пример с typename, но использование лямбда-аргументов C++14 решило проблему:

    auto text = "some {test} data";
    regex re( "\\{([^\\}]*)\\}" );
    text  = boost::regex_replace( text, re, [&](auto & what) {
        return what.str();
    });
Другие вопросы по тегам