C#中字符串类的一些实用技巧
本次讲解的环境全部处于
LINQPad8
中进行,
LINQPad
号称是轻量级的 .NET 开发者操练场,它可以快速编写代码、输出格式化结果、连接数据库、管理项目等以下代码中出现
.Dump()
方法的,请不要慌张,这个其实就是LINQPad
的输出方法,可以理解为C#中的console.write()
。
分割字符串
Split()方法
var message = "hello C# String!";
message.Split(" ")
这是Split()
方法的基础方法,这个就不多说了,想要以哪些符号作为分隔,直接在Split()
方法中添加即可,这里我们是以一个空格作为分隔符输出我们的字符串,以下是我们的输出结果。
然而我们的
Split()
方法是有重载的,换句话来说就是你还可以给Split()
传入别的参数来实现对应的功能,接下来我们来介绍一下这部分内容
Split()方法重载
分割指定个数的字符串
var message = "hello C# String!";
message.Split(" ", 2).Dump();
以上代码代表的含义就是我们要把message字符串的内容以空格为分隔符,将其分割成两个字符串,这里的分割是从左往右进行的,要是分割到第二个空格之后将把剩余的字符串全部视作一个,即使剩余的字符串中还有空格符号。以下是效果图:
去除前导空格和后导空格
这里我们
Split()
重载参数中有一个叫TrimEntries
的内置方法,这个方法能够将分离出来的新字符串去除前导和后导的空格,效果如下所示:
看到没,原先Hello前面的空格已经没咯~
去除分割的空字符串
假如我们分割出来的字符串是一个空字符串,这时候
RemoveEmptyEntries
就排上用场了
var message = "Hello, C# String! ";
message.Split(" ").Dump();
这里们以空格为截断条件,我们看一下效果图:
我们可以发现最后是多了一个空的字符串的,显示我们只要再
Split()
方法中加上RemoveEmptyEntries
即可:
var message = "Hello, C# String! ";
message.Split(" ",StringSplitOptions.RemoveEmptyEntries).Dump();
我们此时来看一下效果图:
当当当~~是不是发现空字符串已经被消除了呢
查找字符串中的字符索引
IndexOf()方法
var message = "Hello, C# String! ";
message.IndexOf(" ").Dump();
以上是最基础的查询索引的示例,程序将输出字符串中第一个空格的索引值,我们的第一个空格索引是6,故输出结果如下:
IndexOf()方法重载
从指定索引位置开始查找对应字符索引
var message = "Hello, C# String! ";
message.IndexOf(" ",7).Dump();
我们第一个空格的索引位置是6,那我们给
IndexOf
的第二个参数是7,那其就会从索引位置7开始查找,直到找到第二个空格为止。输出结果如下:
忽略大小写进行查找
var message = "Hello, C# String! ";
message.IndexOf("s",StringComparison.OrdinalIgnoreCase).Dump();
我们只要给
Indexof()
加上第二个参数StringComparison.OrdinalIgnoreCase
即可忽略字符大小写进行查找,比如例子中我message
没有小写S,此时我们以忽略大小写模式进行查找小写s,此时结果照样会返回在message
中大S的索引值,效果图如下:
统一换行符
在将这个知识点前我们先来回顾一下三大系统
Windows
、Linux
、Mac
中的换行符。
-
Windows
Windows中\r\n表示回车并换行。
-
Linux
Linux中\n表示回车并换行;
-
Mac
Mac中\r表示回车并换行。
其中\r :将当前位置移到本行开头。又叫回车,对应键盘上的return键。
\n:将当前位置移到下一行开头。又叫换行,newline。也就是说在不同系统中换行是不统一的,如果做出来的系统你是跨平台的应用,那你不能单单就用
\n
表示换行操作。为了统一换行符操作,我们引入一个函数方法来进行统一换行符:Environment.NewLine
Environment.NewLine
这个方法会自动识别对应系统的换行符进行替换,无需手动输入换行符。
string[] messages = {
"Hello",
"World",
"from",
"C#"
};
var lines= string.Join(Environment.NewLine,messages);
lines.Split(Environment.NewLine).Dump();
这里的
messages
是一个字符串数组,此时我们利用Join
方法将里面的每个字符串以Environment.NewLine
拼接起来,也就是每行输出一个字符串。接下来我们来看效果:可以看到我们输出每个字符串都以换行符的形式输出了。
那要是字符串中本身混着多种系统的换行符,此时我们想要将其统一怎么办?接下来我们将使用
ReplaceLineEndings
方法来实现全部统一替换的作用:
var lines="hello\r\nworld\n!";
lines.Length.Dump();
lines.ReplaceLineEndings("\n").Length.Dump();
这里我们lines总共是有14个字符,其中'\n'、'\r'是转义字符算一个占位符号。
lines.ReplaceLineEndings("\n")
的意思则是统一将lines中的所有换行符\r\n
、\n
全部换成\n
,这里的\r\n
被替换成了\n
,所以结果是输出13
:
跨平台路径拼接
咱们先来回顾一下我们普通的字符串拼接方式:
var dir1="Folder";
var dir2="SubFolder";
var fn="readme.md";
var path =dir1 + "\\" + dir2 +"\\" + fn;
path.Dump();
\
是windows系统的路径分隔符,/
则是Linux和Mac系统的路径分隔符,我们知道在编程环境中程序会把\
当作转义字符的标志,所以我们要表示字符\
得用对应的转义字符\\
表示才会输出\
,我们先来看一下以上代码的输出结果:
是不是发现一切正常?好的,我们接下来给dir1加上
\\
,也就是var dir1="Folder\\"
此时我们再来看看结果。发现没有这种情况就多了一个
\
,难道说我们每次要去检查字符串是不是自身就带了\\
么?那样也太crazy了!!,所以我们用C#自带的函数Path
来处理这个字符串拼接问题就有大大的优势~~
var dir1="Folder\\";
var dir2="SubFolder";
var fn="readme.md";
Path.Combine(dir1,dir2,fn).Dump();
我们直接来看输出结果:
可以看到系统会自动处理多于的路径拼接符号,这样就完成了我们上面产生的拼接问题。
字符串传参
这个字眼是不是挺新奇的?给字符串传参?我们用字符串一般不都是这样使用:string st_1="hello",还有新的用法么?是的,string本身就是一个类,我们可以
new
一个出来并给其传参。
输出任意个数重复字符
string st_1= new string('=',20);
st_1.Dump();
这时候呢,我们的st_1就会输出20个'=',是不是觉得很神奇呢?
拼接字符数组中的字符
char[] chars = { 'h', 'e', 'l', 'l', 'o'};
new string(chars).Dump();
我们给string传入字符数组之后,其会自动将其拼接成字符串进行输出:
高效率逆序字符串
这里还有一种应用场景:
var message = "hello, world!";
var array = message.ToCharArray();//将字符串转换为字符数组
Array.Reverse(array);//逆序字符数组
//string.Join("",array).Dump();
var res = new string(array);//将字符数组转换成字符串
res.Dump();
这里的字符串逆序本质还是字符数组的逆序,我们上面首先是利用
ToCharArryay()
方法将字符串转换成了字符数组,然后再进行处理,当然你可以利用string.Join("",array).Dump();
将字符数组进行拼接,但是肯定是没有原生态的字符串传参var res = new string(array);
处理效率来得高。接下来我们看一下输出结果:
字符存在性查询
有时候我们想要验证一下某个字符是否存在于字符串中,那该怎么办呢?有一种办法,我们可以利用
IndexOf()
方法的特性,因为当我们用IndexOf()
方法查找某个字符的索引的时候,假如这个字符不存在字符串中其会返回-1
。利用这个特性,我们检查以下返回的值是否是≥0的就好了。
string message = "hello, world!";
char c ='?';
(message.IndexOf(c)>=0).Dump();
以下是输出结果:
当然本节重点要讲的字符存在性查询不是这个方法,这个方法相对来说效率并不高,接下来我们来介绍一下我们的主角-------
Contains()
方法。
string message = "hello, world!";
char c ='?';
message.Contains(c).Dump();
这里我们的
Contains()
方法会直接返回布尔(bool)型的值,如果字符存在返回True
,否则返回False
,执行效率比上一个方法要快很多。
字符串比较
CompareTo( )
string message1 = "hello, world!";
string message2 = "hello, world!";
message1.CompareTo(message2).Dump();
CompareTo()
的默认是返回值是数字,比如上面我们代码中message1
和message2
完全相等,其就会返回0
,要是message1
比message2
大则返回1
,繁反正返回-1
。我们可以依据这一点来判定字符串之间的大小。但是我们如果单单想知道俩字符串相不相等而不考虑大小,那我们可以利用更高效的方法Equals()
来判定。
Equals()
string message1 = "hello, world!";
string message2 = "hello, world!";
message1.Equals(message2).Dump();
Equals
反正是bool型的,所以如果完全相等则返回True
,否则返回False
,因为它只会判定是否相等,而不会返回两个字符串谁大谁小,所以其执行效率也高,但是对应的确实就是功能比CompareTo()
要少。
Equals() 忽略大小写比较
string message1 = "hello, world!";
string message2 = "Hello, World!";
message1.Equals(message2,StringComparison.OrdinalIgnoreCase).Dump();
这里我们可以给
Equals
方法传入重载参数StringComparison.OrdinalIgnoreCase
来实现忽略字符串大小写进行比较。一下是输出:
string.Format( ) 方法
string.Format
方法使用占位符语法来指定变量或表达式的插入点。占位符由一对大括号{}
表示,其中包含一个索引(从0开始),这个索引指向方法调用中传递的参数列表中的相应项。
int a = 10;
char b = 'X';
double c = 3.14;
string d = "hello";
string.Format("{0} {1} {2} {3}",a,b,c,d).Dump();
在字符串中,花括号
{}
中的数字表示参数的索引,而这些索引对应于string.Format
方法后面的参数列表。从左到右,这些索引从0开始。每次索引出现,string.Format
会从提供的参数中取出相应位置的参数替换到字符串中,所以相对来说string.Format()
效率会比较低,以下是输出结果:
字符串插值($
字符串)
int a = 10;
char b = 'X';
double c = 3.14;
string d = "hello";
$"{a} {b} {c} {d}".Dump();
字符串插值可不像
sting.Format()
方法那样一个一个索引对应去插入相应的值,其是在底层进行了相应的优化,其运行效率是非常高的,强烈推荐使用!!。
StringBuilder( )
StringBuilder
是.NET中的一个类,旨在提供一种高效的方式来创建和修改字符串。与普通的字符串 (String
) 不同,StringBuilder
允许对存储在其内部的字符串进行动态修改,而不会产生大量的临时字符串实例。这是因为在.NET中,String
类型的对象是不可变的(immutable),意味着一旦一个字符串被创建,它的内容就不能被改变。任何对字符串的修改操作实际上都会创建一个新的字符串对象,这在处理大量字符串操作时可能会导致性能问题。上面的话简单来说就是:
StringBuilder
在.NET中用于高效修改字符串,因为它避免了不可变的String
类型在每次修改时都需创建新对象的开销。总之就是效率比普通的String类高嘛~接下来我们来看实例:
var sb = new StringBuilder();
sb.Append("Hello");
sb.Append(' ');
sb.AppendLine("world!");// 向 StringBuilder 添加字符串 "world!" 并附加一个新行符
sb.Append("ok");
sb.ToString().Dump();
主打的优势就是效果高~~。
以上就是我们本章的所有内容啦~。
停留在世界边缘,与之惜别