我有一个名为hello world的字符串
我需要把"world"换成" chsharp "
我用:
string.Replace("World", "csharp");
但结果是,字符串没有被替换。原因在于区分大小写。原来的字符串包含“世界”,而我试图取代“世界”。
有没有办法避免字符串中的这种区分大小写的情况?替代方法?
我有一个名为hello world的字符串
我需要把"world"换成" chsharp "
我用:
string.Replace("World", "csharp");
但结果是,字符串没有被替换。原因在于区分大小写。原来的字符串包含“世界”,而我试图取代“世界”。
有没有办法避免字符串中的这种区分大小写的情况?替代方法?
当前回答
2.5倍比其他正则表达式方法更快和最有效的方法:
/// <summary>
/// Returns a new string in which all occurrences of a specified string in the current instance are replaced with another
/// specified string according the type of search to use for the specified string.
/// </summary>
/// <param name="str">The string performing the replace method.</param>
/// <param name="oldValue">The string to be replaced.</param>
/// <param name="newValue">The string replace all occurrences of <paramref name="oldValue"/>.
/// If value is equal to <c>null</c>, than all occurrences of <paramref name="oldValue"/> will be removed from the <paramref name="str"/>.</param>
/// <param name="comparisonType">One of the enumeration values that specifies the rules for the search.</param>
/// <returns>A string that is equivalent to the current string except that all instances of <paramref name="oldValue"/> are replaced with <paramref name="newValue"/>.
/// If <paramref name="oldValue"/> is not found in the current instance, the method returns the current instance unchanged.</returns>
[DebuggerStepThrough]
public static string Replace(this string str,
string oldValue, string newValue,
StringComparison comparisonType)
{
// Check inputs.
if (str == null)
{
// Same as original .NET C# string.Replace behavior.
throw new ArgumentNullException(nameof(str));
}
if (str.Length == 0)
{
// Same as original .NET C# string.Replace behavior.
return str;
}
if (oldValue == null)
{
// Same as original .NET C# string.Replace behavior.
throw new ArgumentNullException(nameof(oldValue));
}
if (oldValue.Length == 0)
{
// Same as original .NET C# string.Replace behavior.
throw new ArgumentException("String cannot be of zero length.");
}
//if (oldValue.Equals(newValue, comparisonType))
//{
//This condition has no sense
//It will prevent method from replacesing: "Example", "ExAmPlE", "EXAMPLE" to "example"
//return str;
//}
// Prepare string builder for storing the processed string.
// Note: StringBuilder has a better performance than String by 30-40%.
StringBuilder resultStringBuilder = new StringBuilder(str.Length);
// Analyze the replacement: replace or remove.
bool isReplacementNullOrEmpty = string.IsNullOrEmpty(newValue);
// Replace all values.
const int valueNotFound = -1;
int foundAt;
int startSearchFromIndex = 0;
while ((foundAt = str.IndexOf(oldValue, startSearchFromIndex, comparisonType)) != valueNotFound)
{
// Append all characters until the found replacement.
int charsUntilReplacment = foundAt - startSearchFromIndex;
bool isNothingToAppend = charsUntilReplacment == 0;
if (!isNothingToAppend)
{
resultStringBuilder.Append(str, startSearchFromIndex, charsUntilReplacment);
}
// Process the replacement.
if (!isReplacementNullOrEmpty)
{
resultStringBuilder.Append(newValue);
}
// Prepare start index for the next search.
// This needed to prevent infinite loop, otherwise method always start search
// from the start of the string. For example: if an oldValue == "EXAMPLE", newValue == "example"
// and comparisonType == "any ignore case" will conquer to replacing:
// "EXAMPLE" to "example" to "example" to "example" … infinite loop.
startSearchFromIndex = foundAt + oldValue.Length;
if (startSearchFromIndex == str.Length)
{
// It is end of the input string: no more space for the next search.
// The input string ends with a value that has already been replaced.
// Therefore, the string builder with the result is complete and no further action is required.
return resultStringBuilder.ToString();
}
}
// Append the last part to the result.
int charsUntilStringEnd = str.Length - startSearchFromIndex;
resultStringBuilder.Append(str, startSearchFromIndex, charsUntilStringEnd);
return resultStringBuilder.ToString();
}
注意:忽略case == StringComparison。OrdinalIgnoreCase作为stringcomparisontype的参数。它是替换所有值的最快、不区分大小写的方法。
该方法的优点:
High CPU and MEMORY efficiency; It is the fastest solution, 2.5 times faster than other's methods with regular expressions (proof in the end); Suitable for removing parts from the input string (set newValue to null), optimized for this; Same as original .NET C# string.Replace behavior, same exceptions; Well commented, easy to understand; Simpler – no regular expressions. Regular expressions are always slower because of their versatility (even compiled); This method is well tested and there are no hidden flaws like infinite loop in other's solutions, even highly rated:
@AsValeO: Not适用于Regex语言元素,所以它不是 普遍的方法
这段代码有问题。如果文本为new 是文本的超集,这样可以产生无限循环。
防基准测试:这个解决方案比@Steve B.的regex快2.59倍,代码:
// Results:
// 1/2. Regular expression solution: 4486 milliseconds
// 2/2. Current solution: 1727 milliseconds — 2.59X times FASTER! than regex!
// Notes: the test was started 5 times, the result is an average; release build.
const int benchmarkIterations = 1000000;
const string sourceString = "aaaaddsdsdsdsdsd";
const string oldValue = "D";
const string newValue = "Fod";
long totalLenght = 0;
Stopwatch regexStopwatch = Stopwatch.StartNew();
string tempString1;
for (int i = 0; i < benchmarkIterations; i++)
{
tempString1 = sourceString;
tempString1 = ReplaceCaseInsensitive(tempString1, oldValue, newValue);
totalLenght = totalLenght + tempString1.Length;
}
regexStopwatch.Stop();
Stopwatch currentSolutionStopwatch = Stopwatch.StartNew();
string tempString2;
for (int i = 0; i < benchmarkIterations; i++)
{
tempString2 = sourceString;
tempString2 = tempString2.Replace(oldValue, newValue,
StringComparison.OrdinalIgnoreCase);
totalLenght = totalLenght + tempString2.Length;
}
currentSolutionStopwatch.Stop();
原创创意- @Darky711;感谢@ miner的StringBuilder。
其他回答
您还可以尝试Regex类。
var regex = new regex ("camel", RegexOptions. var regex = new regex。IgnoreCase); var newSentence =正则表达式。替换(句子,“马”);
2.5倍比其他正则表达式方法更快和最有效的方法:
/// <summary>
/// Returns a new string in which all occurrences of a specified string in the current instance are replaced with another
/// specified string according the type of search to use for the specified string.
/// </summary>
/// <param name="str">The string performing the replace method.</param>
/// <param name="oldValue">The string to be replaced.</param>
/// <param name="newValue">The string replace all occurrences of <paramref name="oldValue"/>.
/// If value is equal to <c>null</c>, than all occurrences of <paramref name="oldValue"/> will be removed from the <paramref name="str"/>.</param>
/// <param name="comparisonType">One of the enumeration values that specifies the rules for the search.</param>
/// <returns>A string that is equivalent to the current string except that all instances of <paramref name="oldValue"/> are replaced with <paramref name="newValue"/>.
/// If <paramref name="oldValue"/> is not found in the current instance, the method returns the current instance unchanged.</returns>
[DebuggerStepThrough]
public static string Replace(this string str,
string oldValue, string newValue,
StringComparison comparisonType)
{
// Check inputs.
if (str == null)
{
// Same as original .NET C# string.Replace behavior.
throw new ArgumentNullException(nameof(str));
}
if (str.Length == 0)
{
// Same as original .NET C# string.Replace behavior.
return str;
}
if (oldValue == null)
{
// Same as original .NET C# string.Replace behavior.
throw new ArgumentNullException(nameof(oldValue));
}
if (oldValue.Length == 0)
{
// Same as original .NET C# string.Replace behavior.
throw new ArgumentException("String cannot be of zero length.");
}
//if (oldValue.Equals(newValue, comparisonType))
//{
//This condition has no sense
//It will prevent method from replacesing: "Example", "ExAmPlE", "EXAMPLE" to "example"
//return str;
//}
// Prepare string builder for storing the processed string.
// Note: StringBuilder has a better performance than String by 30-40%.
StringBuilder resultStringBuilder = new StringBuilder(str.Length);
// Analyze the replacement: replace or remove.
bool isReplacementNullOrEmpty = string.IsNullOrEmpty(newValue);
// Replace all values.
const int valueNotFound = -1;
int foundAt;
int startSearchFromIndex = 0;
while ((foundAt = str.IndexOf(oldValue, startSearchFromIndex, comparisonType)) != valueNotFound)
{
// Append all characters until the found replacement.
int charsUntilReplacment = foundAt - startSearchFromIndex;
bool isNothingToAppend = charsUntilReplacment == 0;
if (!isNothingToAppend)
{
resultStringBuilder.Append(str, startSearchFromIndex, charsUntilReplacment);
}
// Process the replacement.
if (!isReplacementNullOrEmpty)
{
resultStringBuilder.Append(newValue);
}
// Prepare start index for the next search.
// This needed to prevent infinite loop, otherwise method always start search
// from the start of the string. For example: if an oldValue == "EXAMPLE", newValue == "example"
// and comparisonType == "any ignore case" will conquer to replacing:
// "EXAMPLE" to "example" to "example" to "example" … infinite loop.
startSearchFromIndex = foundAt + oldValue.Length;
if (startSearchFromIndex == str.Length)
{
// It is end of the input string: no more space for the next search.
// The input string ends with a value that has already been replaced.
// Therefore, the string builder with the result is complete and no further action is required.
return resultStringBuilder.ToString();
}
}
// Append the last part to the result.
int charsUntilStringEnd = str.Length - startSearchFromIndex;
resultStringBuilder.Append(str, startSearchFromIndex, charsUntilStringEnd);
return resultStringBuilder.ToString();
}
注意:忽略case == StringComparison。OrdinalIgnoreCase作为stringcomparisontype的参数。它是替换所有值的最快、不区分大小写的方法。
该方法的优点:
High CPU and MEMORY efficiency; It is the fastest solution, 2.5 times faster than other's methods with regular expressions (proof in the end); Suitable for removing parts from the input string (set newValue to null), optimized for this; Same as original .NET C# string.Replace behavior, same exceptions; Well commented, easy to understand; Simpler – no regular expressions. Regular expressions are always slower because of their versatility (even compiled); This method is well tested and there are no hidden flaws like infinite loop in other's solutions, even highly rated:
@AsValeO: Not适用于Regex语言元素,所以它不是 普遍的方法
这段代码有问题。如果文本为new 是文本的超集,这样可以产生无限循环。
防基准测试:这个解决方案比@Steve B.的regex快2.59倍,代码:
// Results:
// 1/2. Regular expression solution: 4486 milliseconds
// 2/2. Current solution: 1727 milliseconds — 2.59X times FASTER! than regex!
// Notes: the test was started 5 times, the result is an average; release build.
const int benchmarkIterations = 1000000;
const string sourceString = "aaaaddsdsdsdsdsd";
const string oldValue = "D";
const string newValue = "Fod";
long totalLenght = 0;
Stopwatch regexStopwatch = Stopwatch.StartNew();
string tempString1;
for (int i = 0; i < benchmarkIterations; i++)
{
tempString1 = sourceString;
tempString1 = ReplaceCaseInsensitive(tempString1, oldValue, newValue);
totalLenght = totalLenght + tempString1.Length;
}
regexStopwatch.Stop();
Stopwatch currentSolutionStopwatch = Stopwatch.StartNew();
string tempString2;
for (int i = 0; i < benchmarkIterations; i++)
{
tempString2 = sourceString;
tempString2 = tempString2.Replace(oldValue, newValue,
StringComparison.OrdinalIgnoreCase);
totalLenght = totalLenght + tempString2.Length;
}
currentSolutionStopwatch.Stop();
原创创意- @Darky711;感谢@ miner的StringBuilder。
你可以使用Regex并执行不区分大小写的替换:
class Program
{
static void Main()
{
string input = "hello WoRlD";
string result =
Regex.Replace(input, "world", "csharp", RegexOptions.IgnoreCase);
Console.WriteLine(result); // prints "hello csharp"
}
}
(编辑:没有意识到“裸链接”的问题,对不起)
从这里开始:
string myString = "find Me and replace ME";
string strReplace = "me";
myString = Regex.Replace(myString, "me", strReplace, RegexOptions.IgnoreCase);
似乎你不是第一个抱怨字符串不区分大小写的人。
很多使用Regex的建议。如果没有它,这个扩展方法如何:
public static string Replace(this string str, string old, string @new, StringComparison comparison)
{
@new = @new ?? "";
if (string.IsNullOrEmpty(str) || string.IsNullOrEmpty(old) || old.Equals(@new, comparison))
return str;
int foundAt = 0;
while ((foundAt = str.IndexOf(old, foundAt, comparison)) != -1)
{
str = str.Remove(foundAt, old.Length).Insert(foundAt, @new);
foundAt += @new.Length;
}
return str;
}