Как использовать 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();
});