简介
c# 11 引入了原始字符串字面量(raw string literals),这是一个革命性的特性,极大地简化了包含大量特殊字符(如引号、反斜杠、换行符等)的字符串处理。
原始字符串字面量允许创建包含任意文本的字符串,而无需转义特殊字符。它们以至少三个双引号 """ 开始和结束,并且可以跨越多行。
核心特性与优势
核心特点
- 无转义需求:不需要对引号、反斜杠等特殊字符进行转义
- 多行支持:原生支持多行字符串格式
- 空白保留:精确保留源代码中的缩进和格式化
- 灵活分隔符:使用可变数量的双引号作为分隔符
- 字符串插值:可与插值语法无缝结合
与传统字符串对比
| 特性 | 常规字符串 | 逐字字符串(@) | 原始字符串字面量 |
|---|---|---|---|
| 转义需求 | 需要转义特殊字符 | 不需要转义,但对双引号仍需转义 | 完全不需要转义 |
| 多行支持 | 需使用\n等 | 支持 | 原生支持 |
| 缩进保留 | 不保留 | 保留所有缩进 | 智能缩进处理 |
| 引号处理 | \" | "" | 直接使用 |
| json/xml | 可读性差 | 可读性中等 | 完美呈现 |
基本语法
// 基本原始字符串
string basic = """这是一个原始字符串,不需要转义 "引号" 和 \反斜杠""";
// 多行原始字符串
string multiline = """
这是一个
多行原始字符串
可以包含 "引号" 和 \反斜杠
""";
// 包含大括号的原始字符串
string withbraces = """
{ "name": "john", "age": 30 }
""";
核心特性与优势
无需转义特殊字符
// 传统方式(需要转义)
string traditional = "这是一个包含\"引号\"和\\反斜杠的字符串";
// 原始字符串方式(无需转义)
string raw = """这是一个包含"引号"和\反斜杠的字符串""";
// 正则表达式示例
string regexpattern = """^[a-za-z0-9._%+-]+@[a-za-z0-9.-]+\.[a-za-z]{2,}$""";
多行字符串处理
// 传统多行字符串(需要转义和连接)
string oldmultiline = "第一行\n" +
"第二行\n" +
"第三行";
// 原始多行字符串(更简洁)
string newmultiline = """
第一行
第二行
第三行
""";
// json 示例
string json = """
{
"name": "john doe",
"age": 30,
"email": "john@example.com"
}
""";
缩进处理
原始字符串字面量会自动处理缩进,使代码保持整洁:
string getformattedmessage()
{
return """
hello,
this is an indented message.
it preserves the formatting exactly as written.
""";
}
// 输出结果:
// hello,
// this is an indented message.
// it preserves the formatting exactly as written.
引号数量规则
当字符串内容包含三个或更多连续双引号时,需要使用更多引号作为分隔符:
// 内容包含三个双引号 → 使用四个作为分隔符 string triplequotes = """" 这里可以包含 """ 三个引号 """"; // 内容包含四个双引号 → 使用五个作为分隔符 string fourquotes = """"" 这里可以包含 """" 四个引号 """"";
引号数量选择原则
- 分隔符的双引号数量(n)必须大于内容中连续双引号的最大数量(m)
- 最小分隔符数量为3(即使内容没有三个引号)
- 公式:
n > m
多$符号规则
$的数量决定了插值表达式的边界- 一个
$→ 表达式使用{ } - 两个
$$→ 表达式使用{{ }},以此类推
高级用法与技巧
包含更多引号
如果需要字符串中包含三个或更多连续双引号,可以使用更多引号作为分隔符:
// 使用四个引号作为分隔符,以包含三个引号
string withtriplequotes = """"
这个字符串包含三个连续引号: """
"""";
// 使用五个引号作为分隔符,以包含四个引号
string withfourquotes = """""
这个字符串包含四个连续引号: """"
""""";
与字符串插值结合使用
原始字符串可以与字符串插值结合使用,提供更强大的功能:
string name = "john";
int age = 30;
// 基本插值
string interpolated = $$"""
{
"name": "{{name}}",
"age": {{age}}
}
""";
// 复杂插值(使用多个$符号)
string complex = $$$"""
{
"name": "{{{name}}}", // 注意:这里需要三个大括号
"age": {{age}}
}
""";
最小化缩进
原始字符串会自动去除与结束引号对齐的缩进:
string minimalindent = """
first line
second line
third line
"""; // 结束引号的缩进决定了最小缩进
// 等效于:
// "first line\nsecond line\nthird line"
实际应用场景
json 和 xml 处理
// json 配置
string configjson = """
{
"appsettings": {
"timeout": 30,
"retrycount": 3,
"apiurl": "https://api.example.com"
},
"logging": {
"level": "information",
"filepath": "logs/app.log"
}
}
""";
// xml 文档
string xmldocument = """
<?xml version="1.0" encoding="utf-8"?>
<catalog>
<book id="bk101">
<author>gambardella, matthew</author>
<title>xml developer's guide</title>
<genre>computer</genre>
<price>44.95</price>
<publish_date>2000-10-01</publish_date>
<description>an in-depth look at creating applications with xml.</description>
</book>
</catalog>
""";
正则表达式模式
// 复杂的正则表达式(无需转义反斜杠)
string emailpattern = """^[a-za-z0-9._%+-]+@[a-za-z0-9.-]+\.[a-za-z]{2,}$""";
string phonepattern = """^(\+\d{1,3}\s?)?(\(\d{1,4}\)\s?)?\d{1,4}[\s.-]?\d{1,4}[\s.-]?\d{1,9}$""";
// 使用正则表达式
bool isvalidemail = regex.ismatch("test@example.com", emailpattern);
sql 查询
string sqlquery = """
select
u.id,
u.name,
u.email,
count(o.id) as ordercount
from users u
left join orders o on u.id = o.userid
where u.isactive = 1
group by u.id, u.name, u.email
having count(o.id) > 0
order by ordercount desc
""";
代码生成
string generatecsharpclass(string classname, ienumerable<string> properties)
{
return $$"""
public class {{classname}}
{
{{string.join("\n ", properties.select(p => $"public string {p} {{ get; set; }}"))}}
public {{classname}}()
{
}
public override string tostring()
{
return $"{{
{{string.join(", ", properties.select(p => $"{p}={{{p}}}"))}}
}}";
}
}
""";
}
// 使用示例
string classcode = generatecsharpclass("person", new[] { "firstname", "lastname", "age" });
总结
c# 11 的原始字符串字面量是一个强大的特性,它:
- 消除转义需求:无需转义引号、反斜杠等特殊字符
- 支持多行内容:轻松创建多行字符串,保持格式
- 智能缩进处理:自动处理缩进,使代码更整洁
- 与插值结合:支持字符串插值,创建动态内容
- 编译时处理:无运行时性能开销
适用场景:
json/xml/html内容:处理结构化数据- 正则表达式:编写复杂的模式匹配
sql 查询:编写多行数据库查询
- 代码生成:创建模板化代码
- 文档字符串:编写格式化的文档
到此这篇关于c#中的原始字符串字面量全面解析的文章就介绍到这了,更多相关c#原始字符串字面量内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论