c#中较常用的字符串处理技巧:
(补充:字符串为引用类型,栈中只是存了字符串的引用地址,实际字符串值存储在堆中;下边变量s就是字符串 "123" 的引用)
字符串的不可变性:
当给一个字符串重新赋值之后,老值并没有销毁,而是重新开辟一块空间,存储新值。
当程序结束后,GC会扫描整个内存,如果发现有的空间没有被指向,则会立即把它销毁。
访问字符串中的元素:
(1)string类型的变量可以看成char变量的只读数组,所以访问字符串中的每个字符,可以这样访问:
(也就是字符串是由多个char类型组成的,只能访问字符串中的字符,而不能给其赋值)
string str = "abc";
char r = str[0];
(2)访问一个字符串中的某一个字符时,变量类型是 字符(char)类型:
static void Main(string[] args)
{
string str = "abc";
char r = str[0];
Console.WriteLine(r); // 'a'
Console.ReadKey();
}
补充:
1> 改变字符串中的某个字符
2> 将字符串转char类型的数组 string.ToCharArray();
3> 将char类型的数组转字符串 new string(charsArray);
如果想改变字符串中的某个字符,可以先通过转化为char类型的数组,然后,选中数组的某一元素,给赋值,然后在把char类型的数组转化为字符串。
static void Main(string[] args)
{
string s = "abc";
//转为char类型的数组
char[] chars = s.ToCharArray();
chars[0] = '0';
// 在把将字符类型的数组转为字符串
s = new string(chars);
Console.WriteLine(s); // "0bc"
Console.ReadLine();
}
(3)foreach
循环中使用字符串。
static void Main(string[] args)
{
string str = "abc";
foreach (char item in str)
{
Console.WriteLine($"输出的字符:{item}");
}
Console.ReadKey();
}
字符串常用方法:
(4)与数组一样,可以使用 .Length
来访问字符串字符的数量:
static void Main(string[] args)
{
string str = "abc";
Console.WriteLine(str.Length); // 3
Console.ReadKey();
}
(5)ToLower()和ToUpper()
把字符串转换为小写或大写形式:
static void Main(string[] args)
{
string str = "abc";
Console.WriteLine($"{str.ToUpper()},小写:{str.ToLower()}"); // "ABC" "abc"
Console.ReadKey();
}
(6)操作字符串的所有命令,并未真正改变字符串本身,会创建一个新的字符串。
(7)<string>.Trim( )
去除字符串前后空格:
static void Main(string[] args)
{
string str = " abc ";
Console.WriteLine($"{str.Trim()}"); // "abc"
Console.ReadKey();
}
(8)<string>.TrimStart( ) 和 <string>.TrimEnd()
去除字符串前边或者后边的空格
(9)<string>.PadLeft()和<string>.PadRight()
可以在字符串的左边或者右边添加指定元素(书上距离:添加空格、中横线)
static void Main(string[] args)
{
string str = "abc";
// " abc" -> 参数是指定字符串长度,在字符串左侧添加1个空格
Console.WriteLine(str.PadLeft(4));
Console.ReadKey();
}
static void Main(string[] args)
{
string str = "abc";
// "-abc" -> 参数二是在字符串左侧添加的字符(只能添加字符)
Console.WriteLine(str.PadLeft(4, '-'));
Console.ReadKey();
}
static void Main(string[] args)
{
string str = "abc";
// "---abc" -> 在字符串开头添加3个短横线
Console.WriteLine(str.PadLeft(6, '-'));
Console.ReadKey();
}
(10)<string>.split( ) 以指定参数的形式来分割字符串,可以把字符串转字符串类型的数组
此方法提供了6个重载(也就是可以传递6中类型的参数)
下边,我们通过分隔最后却是把字符串中的特殊字符都去掉了,但是问题来了,最后会生成一个包含空字符串的数组,这不是我们想要的,解决此类问题,可以使用第二个参数,下边介绍:
static void Main(string[] args)
{
string str = "h_ello w-or+ld,,,";
char[] chars = { '_', ' ', '-', '+', ',' };
string[] res = str.Split(chars, StringSplitOptions.RemoveEmptyEntries);
Console.WriteLine(item); // {"h", "ello", "w", "or", "ld"}
Console.ReadKey();
}
第二个参数,字符串分个选项,StringSplitOptions,它是一个枚举参数,里边有两个值,分别是:
StringSplitOptions.None:返回值包含空字符串的数组
StringSplitOptions.RemoveEmptyEntries:返回值不包括空字符串的数组
(11)补充:
StringBuilder 大量操作字符串的神器
关于操作字符串的问题:
我们知道,每操作一次字符串,都会在内存中开辟一块空间,而不会去替换之前字符串所在内存空间的值,假设有一个字符串拼接赋值的操作,此时,内存中会产生大量的垃圾,对于程序而言是致命的!
此时,可以使用 StringBuilder 来解决此类问题,先来看下普通情况下的字符串拼接:
如下:
我们使用计时器来计时,最后结果:20s的运行时间,我想让谁都不能接受!!!
static void Main(string[] args)
{
string str = null;
Stopwatch sw = new Stopwatch(); // 创建一个计时器,记录程序运行时间
sw.Start(); // 开始计时
for (int i = 0; i < 100000; i++)
{
str += i; // +号起到拼接的作用
}
sw.Stop(); // 结束计时
Console.WriteLine(sw.Elapsed); // 获取当前对象的总运行时间 00:00:20.8381279
Console.ReadLine();
}
在看下使用 StringBuilder 来看下运行时间:
如下:
我们使用Append方法向实例中追加指定的元素,最后用时:0.01s,是不是感觉秒杀上边的字符串拼接方式!!!
最后,会把实例下边是sb转换为字符串:
static void Main(string[] args)
{
StringBuilder sb = new StringBuilder();
string str = null;
Stopwatch sw = new Stopwatch(); // 创建一个计时器,记录程序运行时间
sw.Start(); // 开始计时
for (int i = 0; i < 100000; i++)
{
sb.Append(i); // 掉用Append方法,想sb对象(实例)追加指定的元素
}
str = sb.ToString();
sw.Stop(); // 结束计时
Console.WriteLine(sw.Elapsed); // 获取当前对象的总运行时间 00:00:00.0132417
Console.ReadLine();
}
关于sb.Append()方法,其中参数,可以传不同类型,19多个重载,可在编辑器中查看。
12、Equals
判断两个字符串 或 两个实例对象是否相等,返回的是bool类型:
static void Main(string[] args)
{
string s1 = "a";
string s2 = "a";
Console.WriteLine(s1.Equals(s2)); // true
Console.ReadLine();
}
Equals还有第二个参数,StringComparison,它是一个枚举类型,通过点的方式来调用其枚举中的值:
经常用到的是:StringComparison.OrdinalIgnoreCase 忽略大小写:
13、bool contains(string value)
判断字符串中是否包含子串 value,包含返回true,否则,返回false
14、string Replace( string oldValue, string newValue )
替换字符串,参数一:被替换的字符串;参数二:替换成的字符串,会返回一个新字符串,在需要时,可把之前字符串重新赋值。
static void Main(string[] args)
{
string str = "abc";
if (str.Contains("a"))
{
str = str.Replace("a", "0");
}
Console.WriteLine(str); // "0bc"
Console.ReadKey();
}
15、string Substring( int startIndex )
经常用到,截取字符串,它只有一个重载
取值范围:从位置startIndex 就是字符串的索引位 开始,一直到最后的字符串最后;它还有第二个参数,截取的长度,只写一个参数时,默认截取到最后,有截取长度时,截取到指定长度;返回一个新字符串。
static void Main(string[] args)
{
string str = "abcdefg";
str = str.Substring(2);
Console.WriteLine(str); // "cdefg"
Console.ReadKey();
}
static void Main(string[] args)
{
string str = "abc";
str = str.Substring(1, 1);
Console.WriteLine(str); // "b"
Console.ReadKey();
}
16、
(1) bool StartsWith(string value, Enum StringComparison)
是否以value开头,返回bool类型,参数二同下;
(2) bool EndsWith( string value, Enum StringComparison)
是否以value结束,返回bool类型,参数二是一个枚举参数,通常使用的是: StringComparison.OrdinalIgnoreCase 可以忽略大小写
static void Main(string[] args)
{
string str = "abc";
bool b = str.StartsWith("A", StringComparison.OrdinalIgnoreCase);
Console.WriteLine(b); // "true"
Console.ReadKey();
}
17、 int IndexOf( string value, int startWith, Enum StringComparison )
指定字符串,在字符串中第一次出现的位置(就是索引位),参数二,可选参数,指定要查找的起始位;参数三,可选参数,枚举参数。找到返回当前的索引位,没找到的话,返回-1 ;此方法有8个重载,详细可到文档 或 vs编辑器查看
(注意:如果indexOf( ) 参数为负数或超出字符串的长度,会报错!!!)
static void Main(string[] args)
{
string str = "abc";
int i = str.IndexOf("A", StringComparison.OrdinalIgnoreCase);
Console.WriteLine(i); // 0
Console.ReadKey();
}
下边找到字符串中所有的a,并且把对应的索引拼接成一个字符串:
class Program
{
static void Main(string[] args)
{
string str = "abacaefa";
string r = GetAllAppointString(str);
Console.WriteLine(r);
Console.ReadKey();
}
public static string GetAllAppointString(string str)
{
// 处理如果字符串第一位就是"a",那么输出的索引就是0,把0转为字符串赋值给s
string s = str.IndexOf("a", 0) == 0 ? str.IndexOf("a", 0).ToString() : null;
int initIndex = 0;
while (str.IndexOf("a", initIndex) != -1)
{
initIndex = str.IndexOf("a", initIndex + 1);
// 这里注意下,如果IndexOf()参数中有负数或者超出字符串长度,会报错!!!
if (initIndex == -1)
{
return s;
}
s += initIndex;
}
return s;
}
}
18、 int LastIndexOf( string value, int startWith, Enum StringComparison )
指定字符串,在字符串中最后一次出现的位置(就是索引位),参数同上。
19、bool string.IsNullOrEmpty(string value)
判断一个字符串是否是Null或者Empty
static void Main(string[] args)
{
string str = "";
bool r = string.IsNullOrEmpty(str);
Console.WriteLine(r); //true
Console.ReadKey();
}
20、string string.Join( string separator )
可以把数组以指定的方式 转换为 字符串, 参数一,在每个元素之间指定的分隔符;参数二,要被转化的元素:
static void Main(string[] args)
{
string[] str = { "ab", "cd", "ef" };
string r = string.Join("-", str);
Console.WriteLine(r); // "ab-cd-ef"
Console.ReadKey();
}
小练习:
读取test.txt中的内容,把每个书名与对应的作者以 "——"中横线连接,如果书名长度 大于6,多出的部分以 "..." 表示。
未完成!