原始字面量
原始字符串字面量(Raw String Literals)可以让你编写包含多行和特殊字符的字符串,而
不需要使用传统的转义序列
使用格式:R"xxx(
字符串
)xxx",我们正常直接使用R"(字符串
)"就行
使用情景
- 正则表达式:正则表达式通常包含大量的反斜杠(\),如果不使用原始字面量,每个反斜杠都需要被转义(例如写成\),这会让代码难以阅读和维护。使用原始字面量可以直接写入正则表达式,无需对特殊字符进行转义。
- 文件路径:在Windows系统中,文件路径使用反斜杠(\)作为分隔符。使用原始字面量可以避免在文件路径中对每个反斜杠进行转义。
- 嵌入代码或脚本:当你需要在C++代码中嵌入其他语言的代码(如HTML, SQL, JSON等)时,原始字面量可以让这些代码直接以它们原本的格式嵌入,而不需要对特殊字符进行转义。
使用示例:
#include<iostream>
#include<string>
#include <regex>
using namespace std;
int main()
{
//用于字符串字面值的原始字符串
string str1 = "\"hello\"";
string str2 = R"("hello")";
cout << "str1: " << str1 << endl;
cout << "str2: " << str2 << endl;
cout << '\n';
//用于路径字面值的原始字符串
string str3 = "F:\\vs2022_code\\C++11";
string str4 = R"(F:\vs2022_code\C++11)";
cout << "str3: " << str3 << endl;
cout << "str4: " << str4 << endl;
cout << '\n';
//用于HTML文档的原始字符串
string str5 = "\n\
<html>\n\
<head>\n\
<title>Title</title>\n\
</head>\n\
<body>\n\
<p>Hello, world!</p>\n\
</body>\n\
</html>";
string str6 = R"(
<html>
<head>
<title>Title</title>
</head>
<body>
<p>Hello, world!</p>
</body>
</html>)";
cout << "str5: " << str5 << endl;
cout << '\n';
cout << "str6: " << str6 << endl;
cout << '\n';
//用于正则表达式的原始字符串,邮箱正则表达式
string email = "test@example.com";
regex pattern(R"(\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b)");
if (regex_match(email, pattern))
{
cout << "Valid email address" << std::endl;
}
else
{
cout << "Invalid email address" << std::endl;
}
return 0;
}
输出
str1: "hello"
str2: "hello"
str3: F:\vs2022_code\C++11
str4: F:\vs2022_code\C++11
str5:
<html>
<head>
<title>Title</title>
</head>
<body>
<p>Hello, world!</p>
</body>
</html>
str6:
<html>
<head>
<title>Title</title>
</head>
<body>
<p>Hello, world!</p>
</body>
</html>
Valid email address
特别注意
- 定界符(Delimiter)冲突: 原始字面量使用一对
R"xxx(和)xxx"
作为标记,当我们使用自定义的定界符是可能就会出现问题,也就是括号左右的xxx
,我们要么不写,要么就要写一样的
string problematic1 = R"foo(This is a string)foo"; //正确
string problematic2 = R"foo(This is a string)zoo"; //错误,括号左右的定界符不同,报错:找不到原始字符串的结束分隔符
- 原始字面量的连接:
多个字面量之间必须有至少一个空格
,不然就会报错,这里添加空格只是起到区分的作用,并不是真的在两个字符串之间添加空格
std::string concatenated1 = R"(First Part)" R"(Second Part)"; // 正确
std::string concatenated2 = R"(First Part)"R"(Second Part)"; // 错误
std::string wrongConcatenation = R"(First Part)""Second Part"; //正确,原始字面量与普通字符串拼接不需要空格区分,即使使用也是忽略
cout << concatenated1 << endl;//输出:First PartSecond Part
cout << wrongConcatenation << endl;//输出:First PartSecond Part
- 不包含转义序列:
原始字面量不处理任何转义序列
。这意味着\n、\t等常用的转义字符在原始字面量中会被当作普通字符处理。这时与普通字符串拼接时应该注意两者的规则
string test = R"foo(This is a \n\t string)foo";
cout << test << endl;//输出:This is a \n\t string