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
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;
}
}
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"
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;
}
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 often do because of its case-insensitive capabilities.
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.
A little off-topic maybe, but while case insensitive replacement is covered by the standard replace function 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")
Result: "Hi, Hello and Ahoi World Test"
Standard case insensitive replacement:
Replace("Hello World Test", "hello", "Hi", , Compare:=CompareMethod.Text)
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.