可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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?
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?
回答1:
Found one in the comments here: 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 Replace function. This is what i always do because of its case-insensitive capabilities (i'm usually a VB.Net programmer).
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.
回答2:
It's not ideal, but you can import Microsoft.VisualBasic
and use Strings.Replace
to do this. Otherwise I think it's case of rolling your own or stick with Regular Expressions.
回答3:
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;
}
}
回答4:
My 2 cents:
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"
回答5:
This is a VB.NET adaptation of rboarman's method with necessary checks for null and empty strings to avoid an infinite loop.
Public Function Replace(ByVal originalString As String, ByVal oldValue As String, newValue As String, ByVal comparisonType As StringComparison) As String
If String.IsNullOrEmpty(originalString) = False AndAlso String.IsNullOrEmpty(oldValue) = False AndAlso IsNothing(newValue) = False 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
回答6:
Well, the built-in String.Replace
just does not support case-insensitive search. It's documented:
This method performs an ordinal
(case-sensitive and
culture-insensitive) search to find
oldValue.
http://msdn.microsoft.com/en-us/library/fk49wtc1.aspx
It should not be, however, too difficult to create your own extension.
回答7:
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.aspx and "Is there an alternative to string.Replace that is case-insensitive?" as well.
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;
}
回答8:
Returns a string in which a specified substring has been replaced with another substring a specified number of times
It has one optional Microsoft.VisualBasic.CompareMethod paramater to specify the kind of comparison to use when evaluating substrings
Dim mystring As String = "One Two Three"
mystring = Replace(mystring, "two", "TWO", 1, , CompareMethod.Text)