C# Replace:一个熟悉而又陌生的替换

科技资讯 投稿 6600 0 评论

C# Replace:一个熟悉而又陌生的替换

前言

返回值中,已将当前字符串中的指定 Unicode 字符或 String 的 所有匹配项,替换为指定的新的 Unicode 字符或 String。

一、String.Replace( 的几个重载

String.Replace 方法)

  Replace(String, String、

  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 类型:

类型 范围 大小 .NET 类型 默认值
char U+0000 到 U+FFFF 16 位 System.Char \0 即 U+0000
// 给 Char 类型的变量赋值可以通过多重方式,如下:
var chars = new[]
{
    'j',        //字符文本
    '\u006A',   //Unicode 转义序列,它是 \u 后跟字符代码的十六进制表示形式(四个符号)
    '\x006A',   //十六进制转义序列,它是 \x 后跟字符代码的十六进制表示形式
    (char106,  //将字符代码的值转换为相应的 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 方法的特定重载,使用的区域性、大小写和排序规则。

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 实例,程序运行结果的区别,见下面的示例:

查看代码
// 以下示例为三种语言("zh-CN", "th-TH", "tr-TR")不同枚举值的测试代码和输出结果:
String[] cultureNames = { "zh-CN", "th-TH", "tr-TR" }; // 中国 泰国 土耳其
String[] strings1 = { "a", "i", "case", };
String[] strings2 = { "a-", "\u0130", "Case" };
StringComparison[] comparisons = (StringComparison[]Enum.GetValues(typeof(StringComparison;
foreach (var cultureName in cultureNames
{
    Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(cultureName;
    Console.WriteLine("Current Culture: {0}", CultureInfo.CurrentCulture.Name;
    for (int ctr = 0; ctr <= strings1.GetUpperBound(0; ctr++
    {
        foreach (var comparison in comparisons
            Console.WriteLine("   {0} = {1} ({2}: {3}", strings1[ctr], strings2[ctr], comparison,
                              String.Equals(strings1[ctr], strings2[ctr], comparison;
        Console.WriteLine(;
    }
    Console.WriteLine(;
}

// 输出结果:
// Current Culture: zh-CN
//    a = a- (CurrentCulture: False //-----注意------
//    a = a- (CurrentCultureIgnoreCase: False //-----注意------
//    a = a- (InvariantCulture: False
//    a = a- (InvariantCultureIgnoreCase: False
//    a = a- (Ordinal: False
//    a = a- (OrdinalIgnoreCase: False
// 
//    i = İ (CurrentCulture: False
//    i = İ (CurrentCultureIgnoreCase: False //-----注意------
//    i = İ (InvariantCulture: False
//    i = İ (InvariantCultureIgnoreCase: False
//    i = İ (Ordinal: False
//    i = İ (OrdinalIgnoreCase: False
// 
//    case = Case (CurrentCulture: False
//    case = Case (CurrentCultureIgnoreCase: True
//    case = Case (InvariantCulture: False
//    case = Case (InvariantCultureIgnoreCase: True
//    case = Case (Ordinal: False
//    case = Case (OrdinalIgnoreCase: True
// 
// 
// Current Culture: th-TH
//    a = a- (CurrentCulture: True //-----注意------
//    a = a- (CurrentCultureIgnoreCase: True //-----注意------
//    a = a- (InvariantCulture: False
//    a = a- (InvariantCultureIgnoreCase: False
//    a = a- (Ordinal: False
//    a = a- (OrdinalIgnoreCase: False
// 
//    i = İ (CurrentCulture: False
//    i = İ (CurrentCultureIgnoreCase: False
//    i = İ (InvariantCulture: False
//    i = İ (InvariantCultureIgnoreCase: False
//    i = İ (Ordinal: False
//    i = İ (OrdinalIgnoreCase: False
// 
//    case = Case (CurrentCulture: False
//    case = Case (CurrentCultureIgnoreCase: True
//    case = Case (InvariantCulture: False
//    case = Case (InvariantCultureIgnoreCase: True
//    case = Case (Ordinal: False
//    case = Case (OrdinalIgnoreCase: True
// 
// 
// Current Culture: tr-TR
//    a = a- (CurrentCulture: False
//    a = a- (CurrentCultureIgnoreCase: False
//    a = a- (InvariantCulture: False
//    a = a- (InvariantCultureIgnoreCase: False
//    a = a- (Ordinal: False
//    a = a- (OrdinalIgnoreCase: False
// 
//    i = İ (CurrentCulture: False
//    i = İ (CurrentCultureIgnoreCase: True //-----注意------
//    i = İ (InvariantCulture: False
//    i = İ (InvariantCultureIgnoreCase: False
//    i = İ (Ordinal: False
//    i = İ (OrdinalIgnoreCase: False
// 
//    case = Case (CurrentCulture: False
//    case = Case (CurrentCultureIgnoreCase: True
//    case = Case (InvariantCulture: False
//    case = Case (InvariantCultureIgnoreCase: True
//    case = Case (Ordinal: False
//    case = Case (OrdinalIgnoreCase: True

4、Replace(String, String, Boolean, CultureInfo

此重载主要介绍下后两个入参。

true:忽略大小写;false:区分大小写。

为空时取当前区域(CultureInfo.CurrentCulture.CompareInfo)。

注:关于 CultureInfo 的详细测试示例,详见上一部分中的折叠代码。

查看代码
 public string Replace(string oldValue, string? newValue, bool ignoreCase, CultureInfo? culture
{
	return ReplaceCore(oldValue, newValue, culture?.CompareInfo, ignoreCase ? CompareOptions.IgnoreCase : CompareOptions.None;
}
private string ReplaceCore(string oldValue, string newValue, CompareInfo ci, CompareOptions options
{
	if ((objectoldValue == null
	{
		throw new ArgumentNullException("oldValue";
	}
	if (oldValue.Length == 0
	{
		throw new ArgumentException(SR.Argument_StringZeroLength, "oldValue";
	}
	return ReplaceCore(this, oldValue.AsSpan(, newValue.AsSpan(, ci ?? CultureInfo.CurrentCulture.CompareInfo, options ?? this;
}
private static string ReplaceCore(ReadOnlySpan<char> searchSpace, ReadOnlySpan<char> oldValue, ReadOnlySpan<char> newValue, CompareInfo compareInfo, CompareOptions options
{
	Span<char> initialBuffer = stackalloc char[256];
	ValueStringBuilder valueStringBuilder = new ValueStringBuilder(initialBuffer;
	valueStringBuilder.EnsureCapacity(searchSpace.Length;
	bool flag = false;
	while (true
	{
		int matchLength;
		int num = compareInfo.IndexOf(searchSpace, oldValue, options, out matchLength;
		if (num < 0 || matchLength == 0
		{
			break;
		}
		valueStringBuilder.Append(searchSpace.Slice(0, num;
		valueStringBuilder.Append(newValue;
		searchSpace = searchSpace.Slice(num + matchLength;
		flag = true;
	}
	if (!flag
	{
		valueStringBuilder.Dispose(;
		return null;
	}
	valueStringBuilder.Append(searchSpace;
	return valueStringBuilder.ToString(;
}

二、Regex.Replace( 的几个常用重载

1、Replace(String, String

在指定的输入字符串(input)内,使用指定的替换字符串(replacement),替换与某个正则表达式模式(需要在实例化 Regex 对象时,将正则表达式传入)匹配的所有的字符串。

// 语法
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 枚举),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*******

参考:String.Replace 方法

     Regex.Replace 方法

注:如有建议或疑问,欢迎留言。

编程笔记 » C# Replace:一个熟悉而又陌生的替换

赞同 (26) or 分享 (0)
游客 发表我的评论   换个身份
取消评论

表情
(0)个小伙伴在吐槽