如何将提升regex_replace与 lambda 函数一起使用

How to use boost regex_replace with a lambda function?

本文关键字:lambda 函数 一起 replace regex      更新时间:2023-10-16

我正在尝试使用 lambda 函数来调用std::string类型的boost::regex_replace。 我没有运气让所有类型都正确。

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/模板化字符类型而不是固定类型。

在此代码中,我收到此错误:/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;

如果你有一个符合 C++11 的编译器,你既不需要 Boost 也不需要 lambda。

要实现相同的目标,您可以使用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的第一个类型参数是双向迭代器类型;因此,例如,标准 typedef boost::smatchmatch_results<std::string::const_iterator>

要修复代码,您需要更正 typedef smatch并删除 lambda 参数what上的引用或使其成为常量引用:

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类型有问题。我找不到带有类型名的工作示例,但是使用 C++14 自动 lambda 参数解决了这个问题:

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