如何将已转义的std::string转换为保留转义符原貌的C++原始字符串?
结论
无法直接从已完成转义的运行时字符串还原得到原始字面量的书写形式,因为转义是编译期行为,编译完成后原始书写信息已经被抹除,运行时只能拿到转义后的字符序列。
原因说明
你书写的代码 std::string str = "t\tt\\" 会在编译阶段完成转义解析,最终存储在str中的字符序列为:
- 普通字符
t - 制表符(ASCII 0x09,由
\t转义得到) - 普通字符
t - 反斜杠(ASCII 0x5c,由
\\转义得到)
运行时程序无法区分这个制表符到底是从字面量\t转义来的,还是从其他输入(比如用户键盘输入的Tab键)得到的,自然没法直接反向得到你期望的原始书写形式。
替代实现方案
如果你只是需要把运行时的特殊字符反向转换为C++字面量风格的转义序列,可以手动实现字符替换逻辑,把特殊字符替换为对应的转义字符串即可,示例代码如下:
#include <string> #include <unordered_map> std::string to_escaped_literal(const std::string& raw_str) { // 定义需要转义的特殊字符和对应转义序列的映射 static const std::unordered_map<char, std::string> escape_rule = { {'\t', R"(\t)"}, {'\n', R"(\n)"}, {'\r', R"(\r)"}, {'\\', R"(\\)"}, {'"', R"(\")"}, {'\'', R"(\')"} }; std::string result; result.reserve(raw_str.size() * 2); // 提前预留空间优化性能 for (char c : raw_str) { auto iter = escape_rule.find(c); if (iter != escape_rule.end()) { result += iter->second; } else { result += c; } } return result; }
调用示例:
std::string str = "t\tt\\"; std::string escaped = to_escaped_literal(str); // 此时escaped的内容就是 "t\\t\\t\\\\",输出显示为 t\t\t\\,和你用R"t\t\\"得到的结果一致
注意事项
这种反向转换存在天然歧义:如果原字符串中本身就存在\和t两个连续的普通字符,转换后会和制表符转义得到的\t完全相同,无法区分,所以只能满足不需要区分来源的展示、序列化场景。
内容的提问来源于stack exchange,提问作者dasfex
相关产品推荐
相关产品推荐

