c++ - 正则表达式替换字符串中是否有与 Perl 的 \L 等效的 C++?
问题描述
在 Perl 中,我可以将字符替换为小写版本,如下所示:
my $str = "HELLO WORLD HOW ARE YOU TODAY";
$str =~ s/([AEIOU])/\L\1/g;
print $str; # HeLLo WoRLD HoW aRe You ToDaY";
我怎样才能用 C++ 做到这一点std::regex_replace
?我可以将它转换成某种模式来激活诸如此类的魔法功能吗?
(真正的搜索模式更复杂,否则我只会在没有正则表达式的情况下手动完成!)
解决方案
不,没有。
最后,我将 SO 中的各种代码修改为以下内容:
#include <regex>
#include <string>
#include <iostream>
// Regex replacement with callback.
// f should be compatible with std::string(const std::smatch&).
// Adapted from code by John Martin (CC-by-SA 3.0).
// (https://stackoverflow.com/a/37516316/560648)
template <typename UnaryFunction>
inline std::string RegexReplace(const std::string& source, const char* const re_str, UnaryFunction f, size_t* numMatches = nullptr)
{
try
{
std::string s;
std::smatch::difference_type positionOfLastMatch = 0;
std::string::const_iterator first = std::begin(source), last = std::end(source);
auto endOfLastMatch = first;
if (numMatches)
*numMatches = 0;
auto callback = [&](const std::smatch& match)
{
auto positionOfThisMatch = match.position(0);
auto diff = positionOfThisMatch - positionOfLastMatch;
auto startOfThisMatch = endOfLastMatch;
std::advance(startOfThisMatch, diff);
s.append(endOfLastMatch, startOfThisMatch);
s.append(f(match));
auto lengthOfMatch = match.length(0);
positionOfLastMatch = positionOfThisMatch + lengthOfMatch;
endOfLastMatch = startOfThisMatch;
std::advance(endOfLastMatch, lengthOfMatch);
if (numMatches)
(*numMatches)++;
};
std::regex re{re_str};
std::sregex_iterator begin(first, last, re), end;
std::for_each(begin, end, callback);
s.append(endOfLastMatch, last);
return s;
}
catch (const std::regex_error&)
{
return "";
}
}
int main()
{
// Change all letters but the first to lower case, but only in
// words starting with a vowel
const std::string str = "HELLO WORLD HOW ARE YOU TODAY";
auto lowercaseSecondSubmatch = [](const std::smatch& match) -> std::string
{
if (match.size() != 3)
return "WTF";
std::string result = match.str(0);
// Lowercase the second submatch
const auto pos = match.position(2) - match.position(0);
const auto len = match.length(2);
const auto start = result.begin() + pos;
const auto end = result.begin() + pos + len;
std::transform(start, end, start, ::tolower);
return result;
};
size_t n = 0;
std::cout << RegexReplace(str, R"REGEX(\b([AEIOUY])([A-Z]+))REGEX", lowercaseSecondSubmatch, &n) << '\n';
std::cout << n << " matches\n";
}
(现场演示)
它当然不是完美的,但它在紧缩中起作用。
推荐阅读
- reactjs - 我应该如何在我的反应新闻应用程序上实施身份验证?
- javascript - firebase httpsCallable 没有被调用/没有响应
- sql - 在存储过程中没有得到预期的结果
- javascript - 如何检测 div 文本的变化?
- node.js - 在“npx create-react-app”“npm start”失败并出现以下错误后:TypeError: Cannot read property 'split' of undefined
- c# - 不可调用的成员“Vector3”不能像方法一样使用。Wander Ai 脚本出错
- reactjs - 如何使axios在具有启动和限制参数的react.js中动态获取请求?
- vim - 如何永久更改 vim 中的默认工作目录(在 Windows 10 上)?
- ubuntu - Tomcat9 中的 webapps 文件夹 - Ubuntu
- java - 如何创建列表
>