在不使用正则表达式的情况下,.Net 中是否存在不区分大小写的字符串替换?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5549426/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is there a case insensitive string replace in .Net without using Regex?
提问by Brian Scott
I recently had to perform some string replacements in .net and found myself developing a regular expression replacement function for this purpose. After getting it to work I couldn't help but think there must be a built in case insensitive replacement operation in .Net that I'm missing?
我最近不得不在 .net 中执行一些字符串替换,并发现自己为此目的开发了一个正则表达式替换函数。让它工作后,我不禁想到 .Net 中必须有一个内置的不区分大小写的替换操作,我错过了?
Surely when there are so many other string operations that support case insensitive comparission such as;
当然,当有这么多其他支持不区分大小写比较的字符串操作时,例如;
var compareStrings = String.Compare("a", "b", blIgnoreCase);
var equalStrings = String.Equals("a", "b", StringComparison.CurrentCultureIgnoreCase);
then there must be a built in equivalent for replace?
那么必须有一个内置的替代品吗?
回答by Tim Schmelter
Found one in the comments here: http://www.codeproject.com/Messages/1835929/this-one-is-even-faster-and-more-flexible-modified.aspx
在这里的评论中找到了一个:http: //www.codeproject.com/Messages/1835929/this-one-is-even-faster-and-more-flexible-modified.aspx
static public string Replace(string original, string pattern, string replacement, StringComparison comparisonType)
{
return Replace(original, pattern, replacement, comparisonType, -1);
}
static public string Replace(string original, string pattern, string replacement, StringComparison comparisonType, int stringBuilderInitialSize)
{
if (original == null)
{
return null;
}
if (String.IsNullOrEmpty(pattern))
{
return original;
}
int posCurrent = 0;
int lenPattern = pattern.Length;
int idxNext = original.IndexOf(pattern, comparisonType);
StringBuilder result = new StringBuilder(stringBuilderInitialSize < 0 ? Math.Min(4096, original.Length) : stringBuilderInitialSize);
while (idxNext >= 0)
{
result.Append(original, posCurrent, idxNext - posCurrent);
result.Append(replacement);
posCurrent = idxNext + lenPattern;
idxNext = original.IndexOf(pattern, posCurrent, comparisonType);
}
result.Append(original, posCurrent, original.Length - posCurrent);
return result.ToString();
}
Should be the fastest, but i haven't checked.
应该是最快的,但我还没有检查过。
Otherwise you should do what Simon suggested and use the VisualBasic Replacefunction. This is what i often do because of its case-insensitive capabilities.
否则,您应该按照西蒙的建议进行操作并使用VisualBasic 替换功能。这是我经常做的,因为它不区分大小写的功能。
string s = "SoftWare";
s = Microsoft.VisualBasic.Strings.Replace(s, "software", "hardware", 1, -1, Constants.vbTextCompare);
You have to add a reference to the Microsoft.VisualBasic dll.
您必须添加对 Microsoft.VisualBasic dll 的引用。
回答by Simon Steele
It's not ideal, but you can import Microsoft.VisualBasicand use Strings.Replaceto do this. Otherwise I think it's case of rolling your own or stick with Regular Expressions.
这并不理想,但您可以导入Microsoft.VisualBasic并使用它Strings.Replace来执行此操作。否则,我认为这是自己滚动或坚持使用正则表达式的情况。
回答by rboarman
Here's an extension method. Not sure where I found it.
这是一个扩展方法。不知道我在哪里找到的。
public static class StringExtensions
{
public static string Replace(this string originalString, string oldValue, string newValue, StringComparison comparisonType)
{
int startIndex = 0;
while (true)
{
startIndex = originalString.IndexOf(oldValue, startIndex, comparisonType);
if (startIndex == -1)
break;
originalString = originalString.Substring(0, startIndex) + newValue + originalString.Substring(startIndex + oldValue.Length);
startIndex += newValue.Length;
}
return originalString;
}
}
回答by KyleMit
Update in .NET Core 2.0+ (August 2017)
.NET Core 2.0+ 中的更新(2017 年 8 月)
This is natively available in .NET Core 2.0+with String.Replacewhich has the following overloads
这在 .NET Core 2.0 +中原生可用,String.Replace它具有以下重载
public string Replace (string oldValue, string newValue, StringComparison comparisonType);
public string Replace (string oldValue, string newValue, bool ignoreCase, System.Globalization.CultureInfo culture);
So you can use either like this:
所以你可以这样使用:
"A".Replace("a", "b", StringComparison.CurrentCultureIgnoreCase);
"A".Replace("a", "b", true, CultureInfo.CurrentCulture);
PS: You can browse .NET Core sourceif you want to see how MS implemented it
PS:如果你想看看微软是如何实现它的,你可以浏览 .NET Core 源代码
Legacy .NET Framework 4.8-option for VB Projects
Legacy .NET Framework 4.8 -VB 项目的选项
Visual Basic has an Option Comparesetting which can be set to Binaryor Text
Visual Basic 有一个Option Compare设置,可以设置为Binary或Text
Setting to Textwill make all string comparisons across your project case insensitive by default.
Text默认情况下,设置为将使项目中的所有字符串比较不区分大小写。
So, as other answers have suggested, if you are pulling in the Microsoft.VisualBasic.dll, when calling Strings.Replaceif you don't explicitly pass a CompareMethodthe method will actually defer to the Compareoption for your file or projectusing the [OptionCompare]Parameter Attribute
因此,正如其他答案所建议的那样,如果您正在拉入Microsoft.VisualBasic.dll,则在调用时Strings.Replace如果您没有明确传递 aCompareMethod该方法实际上Compare将使用[OptionCompare]参数属性推迟到您的文件或项目的选项
So either of the following will also work (top option only available in VB , but both rely on VisualBasic.dll)
因此,以下任一方法也可以使用(顶部选项仅在 VB 中可用,但都依赖于 VisualBasic.dll)
Option Compare Text
Replace("A","a","b")
Replace("A","a","b", Compare := CompareMethod.Text)
回答by Guru Josh
This is a VB.NET adaptation of rboarman's answer abovewith the necessary checks for null and empty strings to avoid an infinite loop.
这是上面 rboarman 答案的 VB.NET 改编版,对空字符串和空字符串进行了必要的检查,以避免无限循环。
Public Function Replace(ByVal originalString As String,
ByVal oldValue As String,
ByVal newValue As String,
ByVal comparisonType As StringComparison) As String
If Not String.IsNullOrEmpty(originalString) AndAlso
Not String.IsNullOrEmpty(oldValue) AndAlso
newValue IsNot Nothing Then
Dim startIndex As Int32
Do While True
startIndex = originalString.IndexOf(oldValue, startIndex, comparisonType)
If startIndex = -1 Then Exit Do
originalString = originalString.Substring(0, startIndex) & newValue &
originalString.Substring(startIndex + oldValue.Length)
startIndex += newValue.Length
Loop
End If
Return originalString
End Function
回答by Eric Boumendil
My 2 cents:
我的 2 美分:
public static string Replace(this string originalString, string oldValue, string newValue, StringComparison comparisonType)
{
if (originalString == null)
return null;
if (oldValue == null)
throw new ArgumentNullException("oldValue");
if (oldValue == string.Empty)
return originalString;
if (newValue == null)
throw new ArgumentNullException("newValue");
const int indexNotFound = -1;
int startIndex = 0, index = 0;
while ((index = originalString.IndexOf(oldValue, startIndex, comparisonType)) != indexNotFound)
{
originalString = originalString.Substring(0, index) + newValue + originalString.Substring(index + oldValue.Length);
startIndex = index + newValue.Length;
}
return originalString;
}
Replace("FOOBAR", "O", "za", StringComparison.OrdinalIgnoreCase);
// "FzazaBAR"
Replace("", "O", "za", StringComparison.OrdinalIgnoreCase);
// ""
Replace("FOO", "BAR", "", StringComparison.OrdinalIgnoreCase);
// "FOO"
Replace("FOO", "F", "", StringComparison.OrdinalIgnoreCase);
// "OO"
Replace("FOO", "", "BAR", StringComparison.OrdinalIgnoreCase);
// "FOO"
回答by Pankti Shah
You can use Microsoft.VisualBasic.Strings.Replaceand pass in Microsoft.VisualBasic.CompareMethod.Textto do a case insensitive replace like this:
您可以使用并传入进行不区分大小写的替换,如下所示:Microsoft.VisualBasic.Strings.ReplaceMicrosoft.VisualBasic.CompareMethod.Text
Dim myString As String = "One Two Three"
myString = Replace(myString, "two", "TWO", Compare:= CompareMethod.Text)
回答by scradam
I know of no canned instance in the framework, but here's another extension method version with a minimal amount of statements (although maybe not the fastest), for fun. More versions of replacement functions are posted at http://www.codeproject.com/KB/string/fastestcscaseinsstringrep.aspxand "Is there an alternative to string.Replace that is case-insensitive?" as well.
我知道框架中没有固定实例,但这是另一个具有最少语句的扩展方法版本(虽然可能不是最快的),为了好玩。更多版本的替换函数发布在http://www.codeproject.com/KB/string/fastestcscaseinsstringrep.aspx和“是否有不区分大小写的 string.Replace 替代方法?”。
public static string ReplaceIgnoreCase(this string alterableString, string oldValue, string newValue){
if(alterableString == null) return null;
for(
int i = alterableString.IndexOf(oldValue, System.StringComparison.CurrentCultureIgnoreCase);
i > -1;
i = alterableString.IndexOf(oldValue, i+newValue.Length, System.StringComparison.CurrentCultureIgnoreCase)
) alterableString =
alterableString.Substring(0, i)
+newValue
+alterableString.Substring(i+oldValue.Length)
;
return alterableString;
}
回答by Schnickelfritz
A little off-topic maybe, but while case insensitive replacement is covered by the standard replacefunction since (?), here a little function that adds text before and/or after a substring without changing the case of the substring:
可能有点题外话,但是虽然不区分大小写的替换由(?) 以来的标准替换函数涵盖,这里有一个小函数在子字符串之前和/或之后添加文本而不改变子字符串的大小写:
Public Shared Function StrWrap(Haystack As String, Needle As String, Optional AddBefore As String = "", Optional AddAfter As String = "") As String
Dim Index = Haystack.ToLower.IndexOf(Needle.ToLower)
If Index < 0 Then Return Haystack
Return Haystack.Substring(0, Index) + AddBefore + Haystack.Substring(Index, Needle.Length) + AddAfter + Haystack.Substring(Index + Needle.Length)
End Function
Usage: StrWrap("Hello World Test", "hello", "Hi, ", " and Ahoi")
用法: StrWrap("Hello World Test", "hello", "Hi, ", " and Ahoi")
Result: "Hi, Hello and Ahoi World Test"
结果:“嗨,你好,Ahoi 世界测试”
Standard case insensitive replacement:
标准不区分大小写的替换:
Replace("Hello World Test", "hello", "Hi", , Compare:=CompareMethod.Text)
Replace("Hello World Test", "hello", "Hi", , Compare:=CompareMethod.Text)

