C# Replace:一个熟悉而又陌生的替换
C# Replace:一个熟悉而又陌生的替换
前言
Replace 的作用就是,通过指定内容的替换,返回一个新字符串。
返回值中,已将当前字符串中的指定 Unicode 字符或 String 的 所有匹配项,替换为指定的新的 Unicode 字符或 String。
一、String.Replace() 的几个重载
String.Replace() 总共有四个重载,分别是:(详见官网:String.Replace 方法)
Replace(Char, Char)、
Replace(String, String)、
Replace(String, String, StringComparison)、
Replace(String, String, Boolean, CultureInfo)。
下面来逐个简单介绍下。
1、Replace(Char, Char)
| // 作用: | |
| // 将实例中出现的所有指定 Unicode 字符都替换为另一个指定的 Unicode 字符。 | |
| // 语法: | |
| public string Replace (char oldChar, char newChar); | 
代码示例:
| String str = "1 2 3 4 5 6 7 8 9"; | |
| Console.WriteLine($"Original string: {str}"); | |
| Console.WriteLine($"CSV string: {str.Replace(' ', ',')}"); | |
| // 输出结果: | |
| // Original string: "1 2 3 4 5 6 7 8 9" | |
| // CSV string: "1,2,3,4,5,6,7,8,9" | 
现在补充一下关于 Char 类型:
char 类型关键字是 .NET System.Char 结构类型的别名,它表示 Unicode UTF-16 字符。
| 类型 | 范围 | 大小 | .NET 类型 | 默认值 | 
| char | U+0000 到 U+FFFF | 16 位 | System.Char | \0 即 U+0000 | 
| // 给 Char 类型的变量赋值可以通过多重方式,如下: | |
| var chars = new[] | |
| { | |
| 'j', //字符文本 | |
| '\u006A', //Unicode 转义序列,它是 \u 后跟字符代码的十六进制表示形式(四个符号) | |
| '\x006A', //十六进制转义序列,它是 \x 后跟字符代码的十六进制表示形式 | |
| (char)106, //将字符代码的值转换为相应的 char 值 | |
| }; | |
| Console.WriteLine(string.Join(" ", chars)); | |
| // 输出的值相同: j j j j | 
char 类型可隐式转换为以下整型类型:ushort、int、uint、long 和 ulong。
也可以隐式转换为内置浮点数值类型:float、double 和 decimal。
可以显式转换为 sbyte、byte 和 short 整型类型。
2、String.Replace(String, String)
| // 作用: | |
| // 实例中出现的所有指定字符串都替换为另一个指定的字符串 | |
| // 语法: | |
| public string Replace (char oldString, char newString); | 
示例:
| // 目的:将错误的单词更正 | |
| string errString = "This docment uses 3 other docments to docment the docmentation"; | |
| Console.WriteLine($"The original string is:{Environment.NewLine}'{errString}'{Environment.NewLine}"); | |
| // 正确的拼写应该为 "document" | |
| string correctString = errString.Replace("docment", "document"); | |
| Console.WriteLine($"After correcting the string, the result is:{Environment.NewLine}'{correctString}'"); | |
| // 输出结果: | |
| // The original string is: | |
| // 'This docment uses 3 other docments to docment the docmentation' | |
| // | |
| // After correcting the string, the result is: | |
| // 'This document uses 3 other documents to document the documentation' | |
| // | 
另一个示例:
| // 可进行连续多次替换操作 | |
| String s = "aaa"; | |
| Console.WriteLine($"The initial string: '{s}'"); | |
| s = s.Replace("a", "b").Replace("b", "c").Replace("c", "d"); | |
| Console.WriteLine($"The final string: '{s}'"); | |
| // 如果 newString 为 null,则将 oldString 的匹配项全部删掉 | |
| s = s.Replace("dd", null); | |
| Console.WriteLine($"The new string: '{s}'"); | |
| // 输出结果: | |
| //The initial string: 'aaa' | |
| //The final string: 'ddd' | |
| //The new string: 'd' | 
3、Replace(String, String, StringComparison)
相较于上一个重载,新增了一个入参枚举类型 StringComparison(详见官网:StringComparison 枚举)。作用是:指定供 Compare(String, String) 和 Equals(Object) 方法的特定重载,使用的区域性、大小写和排序规则。
相关源代码如下,可以看出,不同的 StringComparison 参数值对应的操作不同,最主要的区别就是是否添加参数 CultureInfo。
| public string Replace(string oldValue, string? newValue, StringComparison comparisonType) | |
| { | |
| switch (comparisonType) | |
| { | |
| case StringComparison.CurrentCulture: | |
| case StringComparison.CurrentCultureIgnoreCase: | |
| return ReplaceCore(oldValue, newValue, CultureInfo.CurrentCulture.CompareInfo, | |
| GetCaseCompareOfComparisonCulture(comparisonType)); | |
| case StringComparison.InvariantCulture: | |
| case StringComparison.InvariantCultureIgnoreCase: | |
| return ReplaceCore(oldValue, newValue, CompareInfo.Invariant, | |
| GetCaseCompareOfComparisonCulture(comparisonType)); | |
| case StringComparison.Ordinal: | |
| return Replace(oldValue, newValue); | |
| case StringComparison.OrdinalIgnoreCase: | |
| return ReplaceCore(oldValue, newValue, CompareInfo.Invariant, CompareOptions.OrdinalIgnoreCase); | |
| default: | |
| throw new ArgumentException(SR.NotSupported_StringComparison, "comparisonType"); | |
| } | |
| } | 
关于不同区域的不同 CultureInfo 实例,程序运行结果的区别,见下面的示例:
查看代码4、Replace(String, String, Boolean, CultureInfo)
此重载主要介绍下后两个入参。
Boolean:布尔类型入参,默认 false。true:忽略大小写;false:区分大小写。
CultureInfo:指定代码的区域性,允许为 null,但必须站位。为空时取当前区域(CultureInfo.CurrentCulture.CompareInfo)。
注:关于 CultureInfo 的详细测试示例,详见上一部分中的折叠代码。
以下是当前重载的部分源码:
查看代码二、Regex.Replace() 的几个常用重载
1、Replace(String, String)
在指定的输入字符串(input)内,使用指定的替换字符串(replacement),替换与某个正则表达式模式(需要在实例化 Regex 对象时,将正则表达式传入)匹配的所有的字符串。
关于正则表达式可参考博主另一篇文章:C# 正则表达式常用的符号和模式解析
| // 语法 | |
| public string Replace (string input, string replacement); | 
下面是一个简单的示例:
| // 目的是将多余的空格去掉 | |
| string input = "This is text with far too much white space."; | |
| string pattern = "\\s+"; // \s:匹配任何空白字符;+:匹配一次或多次 | |
| string replacement = " "; | |
| Regex rgx = new Regex(pattern); // 实例化时传入正则表达式 | |
| string result = rgx.Replace(input, replacement); | |
| Console.WriteLine("Original String: {0}", input); | |
| Console.WriteLine("Replacement String: {0}", result); | |
| // 输出结果: | |
| // Original String: This is text with far too much white space. | |
| // Replacement String: This is text with far too much white space. | 
2、Replace(String, String, String)
在指定的输入字符串内(input),使用指定的替换字符串(replacement)替换与指定正则表达式(pattern)匹配的所有字符串。
| // 语法: | |
| public static string Replace (string input, string pattern, string replacement); | 
| // 目的:将多余的空格去掉 | |
| string input = "This is text with far too much white space."; | |
| string pattern = "\\s+"; | |
| // 注:\s 匹配任何空白字符,包括空格、制表符、换页符等 | |
| // 注:+ 重复一次或多次 | |
| string replacement = " "; // 将连续出现的多个空格,替换为一个 | |
| string result = Regex.Replace(input, pattern, replacement); | |
| Console.WriteLine("Original String: {0}", input); | |
| Console.WriteLine("Replacement String: {0}", result); | |
| // 输出结果: | |
| //Original String: This is text with far too much white space. | |
| //Replacement String: This is text with far too much white space. | 
3、Replace(String, String, Int32, Int32)
在指定输入子字符串(input)内,使用指定替换字符串(replacement)替换与某个正则表达式模式匹配的字符串(其数目为指定的最大数目)。startat 是匹配开始的位置。
| // 语法: | |
| public string Replace (string input, string replacement, int count, int startat); | 
下面是一个示例:
| // 目的:添加双倍行距 | |
| string input = "Instantiating a New Type\n" + | |
| "Generally, there are two ways that an\n" + | |
| "instance of a class or structure can\n" + | |
| "be instantiated. "; | |
| Console.WriteLine("原内容:"); | |
| Console.WriteLine(input); | |
| // .:匹配除‘\n’之外的任何单个字符;*:匹配零次或多次 | |
| string pattern = "^.*$"; // ^.*$ 在这里就是匹配每一行中‘\n’前边的字符串 | |
| string replacement = "\n$&"; // 在匹配项前添加‘\n’;$&:代表匹配内容 | |
| Regex rgx = new Regex(pattern, RegexOptions.Multiline); // Multiline:多行模式,不仅仅在整个字符串的开头和结尾匹配 | |
| string result = string.Empty; | |
| Match match = rgx.Match(input); // 判断能否匹配 | |
| if (match.Success) | |
| result = rgx.Replace(input, | |
| replacement, | |
| -1, // >= 0 时,就是匹配具体次数,= -1 时就是不限制次数 | |
| match.Index + match.Length + 1 // 作用就是跳过第一个匹配项(第一行不做处理) | |
| // 当第一次匹配时:Index=0,length=除了‘\n’之外的长度,最后再 +1 就是第一行全部的内容 | |
| ); | |
| Console.WriteLine("结果内容:"); | |
| Console.WriteLine(result); | |
| // 输出结果: | |
| // 原内容: | |
| // Instantiating a New Type | |
| // Generally, there are two ways that an | |
| // instance of a class or structure can | |
| // be instantiated. | |
| // 结果内容: | |
| // Instantiating a New Type | |
| // | |
| // Generally, there are two ways that an | |
| // | |
| // instance of a class or structure can | |
| // | |
| // be instantiated. | 
4、Replace(String, String, MatchEvaluator, RegexOptions, TimeSpan)
在入参字符串(input)中,进行正则表达式(pattern)的匹配,匹配成功的,传递给 MatchEvaluator 委托(evaluator)处理完成后,替换原匹配值。
RegexOptions 为匹配操作配置项(关于 RegexOptions 详见官网:RegexOptions 枚举),TimeSpan 为超时时间间隔。
| public static string Replace (string input, string pattern, | |
| System.Text.RegularExpressions.MatchEvaluator evaluator, | |
| System.Text.RegularExpressions.RegexOptions options, | |
| TimeSpan matchTimeout); | 
下面是一个示例:
| // 目的:将输入的每个单词中的字母顺序随机打乱,再一起输出 | |
| static void Main(string[] args) | |
| { | |
| string words = "letter alphabetical missing lack release " + | |
| "penchant slack acryllic laundry cease"; | |
| string pattern = @"\w+ # Matches all the characters in a word."; | |
| MatchEvaluator evaluator = new MatchEvaluator(WordScrambler); // WordScrambler:回调函数 | |
| Console.WriteLine("Original words:"); | |
| Console.WriteLine(words); | |
| Console.WriteLine(); | |
| try | |
| { | |
| Console.WriteLine("Scrambled words:"); | |
| Console.WriteLine(Regex.Replace(words, pattern, evaluator, | |
| RegexOptions.IgnorePatternWhitespace, TimeSpan.FromSeconds(2))); | |
| } | |
| catch (RegexMatchTimeoutException) | |
| { | |
| Console.WriteLine("Word Scramble operation timed out."); | |
| Console.WriteLine("Returned words:"); | |
| } | |
| } | |
| /// <summary> | |
| /// 回调:对全部匹配项逐一进行操作 | |
| /// </summary> | |
| /// <param name="match"></param> | |
| /// <returns></returns> | |
| public static string WordScrambler(Match match) | |
| { | |
| int arraySize = match.Value.Length; | |
| double[] keys = new double[arraySize]; // 存放随机数 | |
| char[] letters = new char[arraySize]; // 存放字母 | |
| Random rnd = new Random(); | |
| for (int ctr = 0; ctr < match.Value.Length; ctr++) | |
| { | |
| keys[ctr] = rnd.NextDouble(); // 生成随机数,用于重新排序 | |
| letters[ctr] = match.Value[ctr]; // 将输入参单词数拆解为字母数组 | |
| } | |
| Array.Sort(keys, letters, 0, arraySize, Comparer.Default); // 重新根据随机数大小排序 | |
| return new String(letters); | |
| } | |
| // 输出结果: | |
| // Original words: | |
| // letter alphabetical missing lack release penchant slack acryllic laundry cease | |
| // | |
| // Scrambled words: | |
| // eltetr aeplbtaiaclh ignisms lkac elsaree nchetapn acksl lcyaricl udarnly casee | 
三、关于 Replace 的实际需求简单示例
1、全部替换匹配项
| string input = "Instantiating Instantiating Instantiating Instantiating"; | |
| Console.WriteLine("----原内容----"); | |
| Console.WriteLine(input); | |
| string result = input.Replace("tiating","*******"); | |
| Console.WriteLine("----结果内容----"); | |
| Console.WriteLine(result); | |
| // ----原内容---- | |
| // Instantiating Instantiating Instantiating Instantiating | |
| // ----结果内容---- | |
| // Instan******* Instan******* Instan******* Instan******* | 
2、仅替换第一个匹配项
| string input = "Instantiating Instantiating Instantiating Instantiating"; | |
| Console.WriteLine("----原内容----"); | |
| Console.WriteLine(input); | |
| Regex regex = new Regex("tiating"); | |
| string result = regex.Replace(input, "*******",1); | |
| Console.WriteLine("----结果内容----"); | |
| Console.WriteLine(result); | |
| // ----原内容---- | |
| // Instantiating Instantiating Instantiating Instantiating | |
| // ----结果内容---- | |
| // Instan******* Instantiating Instantiating Instantiating | 
3、仅替换最后一个匹配项
| string input = "Instantiating Instantiating Instantiating Instantiating"; | |
| Console.WriteLine("----原内容----"); | |
| Console.WriteLine(input); | |
| Match match = Regex.Match(input, "tiating",RegexOptions.RightToLeft); | |
| string first = input.Substring(0, match.Index); | |
| string last = input.Length == first.Length + match.Length ? "" : | |
| input.Substring(first.Length + match.Length,input.Length-(first.Length + match.Length)); | |
| string result = $"{first}*******{last}"; | |
| Console.WriteLine("----结果内容----"); | |
| Console.WriteLine(result); | |
| // 两次测试结果: | |
| // ----原内容---- | |
| // Instantiating Instantiating Instantiating Instantiating 345 | |
| // ----结果内容---- | |
| // Instantiating Instantiating Instantiating Instan******* 345 | |
| // ----原内容---- | |
| // Instantiating Instantiating Instantiating Instantiating | |
| // ----结果内容---- | |
| // Instantiating Instantiating Instantiating Instan******* | 
注:如有建议或疑问,欢迎留言。
本文来自博客园,作者:橙子家,微信号:zfy1070491745,有任何疑问欢迎沟通,一起成长! 您的支持,博主的动力!
 
                    
                 
                
            
         
 浙公网安备 33010602011771号
浙公网安备 33010602011771号