"hello world"라는 문자열이 있습니다
"world"라는 단어를 "csharp"로 바꿔야합니다
이를 위해 나는 다음을 사용한다.
string.Replace("World", "csharp");
그러나 결과적으로 문자열을 교체하지 않습니다. 이유는 대소 문자를 구분하기 때문입니다. 원래 문자열에 "world"가 포함되어 있지만 "World"를 바꾸려고합니다.
string에서 대소 문자를 구분할 수있는 방법이 있습니까?
"hello world"라는 문자열이 있습니다
"world"라는 단어를 "csharp"로 바꿔야합니다
이를 위해 나는 다음을 사용한다.
string.Replace("World", "csharp");
그러나 결과적으로 문자열을 교체하지 않습니다. 이유는 대소 문자를 구분하기 때문입니다. 원래 문자열에 "world"가 포함되어 있지만 "World"를 바꾸려고합니다.
string에서 대소 문자를 구분할 수있는 방법이 있습니까?
답변:
정규식 을 사용하고 대소 문자를 구분하지 않는 바꾸기를 수행 할 수 있습니다 .
class Program
{
static void Main()
{
string input = "hello WoRlD";
string result =
Regex.Replace(input, "world", "csharp", RegexOptions.IgnoreCase);
Console.WriteLine(result); // prints "hello csharp"
}
}
hello. world?
정규식 연산자를 포함하거나 다른 것을 쓰지 않는 것이 좋습니다 .
var search = "world";
var replacement = "csharp";
string result = Regex.Replace(
stringToLookInto,
Regex.Escape(search),
replacement.Replace("$","$$"),
RegexOptions.IgnoreCase
);
Regex.Escape는 사용자 입력에 의존하는 경우 수에 포함 된 유용 정규식 언어 요소를
최신 정보
의견 덕분에 실제로 교체 문자열을 벗어날 필요가 없습니다.
using System;
using System.Text.RegularExpressions;
public class Program
{
public static void Main()
{
var tests = new[] {
new { Input="abcdef", Search="abc", Replacement="xyz", Expected="xyzdef" },
new { Input="ABCdef", Search="abc", Replacement="xyz", Expected="xyzdef" },
new { Input="A*BCdef", Search="a*bc", Replacement="xyz", Expected="xyzdef" },
new { Input="abcdef", Search="abc", Replacement="x*yz", Expected="x*yzdef" },
new { Input="abcdef", Search="abc", Replacement="$", Expected="$def" },
};
foreach(var test in tests){
var result = ReplaceCaseInsensitive(test.Input, test.Search, test.Replacement);
Console.WriteLine(
"Success: {0}, Actual: {1}, {2}",
result == test.Expected,
result,
test
);
}
}
private static string ReplaceCaseInsensitive(string input, string search, string replacement){
string result = Regex.Replace(
input,
Regex.Escape(search),
replacement.Replace("$","$$"),
RegexOptions.IgnoreCase
);
return result;
}
}
출력은 다음과 같습니다.
Success: True, Actual: xyzdef, { Input = abcdef, Search = abc, Replacement = xyz, Expected = xyzdef }
Success: True, Actual: xyzdef, { Input = ABCdef, Search = abc, Replacement = xyz, Expected = xyzdef }
Success: True, Actual: xyzdef, { Input = A*BCdef, Search = a*bc, Replacement = xyz, Expected = xyzdef }
Success: True, Actual: x*yzdef, { Input = abcdef, Search = abc, Replacement = x*yz, Expected = x*yzdef}
Success: True, Actual: $def, { Input = abcdef, Search = abc, Replacement = $, Expected = $def }
Regex.Escape
는 좋지 않습니다. 특수 문자 앞에 백 슬래시가 붙습니다. 가장 좋은 방법은 .Replace ( "$", "$$")입니다. 이것은 다소 바보입니다 ( stackoverflow.com/a/10078353 ).
2.5X FASTER 및 MOST EFFECTIVE 방법은 다른 정규식 방법보다 :
/// <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();
}
참고 :에StringComparison.OrdinalIgnoreCase
대한 매개 변수로 case == 를 무시하십시오StringComparison comparisonType
. 모든 값을 바꾸는 가장 빠르고 대소 문자를 구분하지 않는 방법입니다.
이 방법의 장점 :
newValue
됨
null
).string.Replace
동작과 동일하지만 예외는 동일합니다.@ AsValeO : Regex 언어 요소와 함께 작동하지 않으므로 보편적 인 방법이 아닙니다.
@ Mike Stillion :이 코드에 문제가 있습니다. new의 텍스트가 이전 텍스트의 수퍼 세트 인 경우 무한 루프가 발생할 수 있습니다.
벤치 마크 방지 :이 솔루션은 @Steve B.의 정규식보다 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; 에 @MinerR 감사합니다 StringBuilder
.
String
. 그러나,이 StringBuilder
정말 빠른 것입니다 30-40% 댄 String
. 솔루션을 업데이트했습니다. 감사합니다;)
확장은 우리의 삶을 더 쉽게 만듭니다 :
static public class StringExtensions
{
static public string ReplaceInsensitive(this string str, string from, string to)
{
str = Regex.Replace(str, from, to, RegexOptions.IgnoreCase);
return str;
}
}
정규식을 사용하는 많은 제안. 이 확장 방법이 없으면 어떻습니까?
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;
}
comparison
매개 변수가 사용되어야한다 IndexOf
대신에,StringComparison.CurrentCultureIgnoreCase
if(old.Equals(@new, comparison)) return @new;
새 문자열은 대문자 / 소문자가 다를 수 있습니다.
Microsoft.VisualBasic 네임 스페이스를 사용 하여이 도우미 함수를 찾을 수 있습니다.
Replace(sourceString, "replacethis", "withthis", , , CompareMethod.Text)
전달 된 비교 유형을 사용하고 프레임 워크와 일치하도록 @ Darky711의 답변을 수정하여 명명 및 XML 주석을 가능한 한 가깝게 만듭니다.
/// <summary>
/// Returns a new string in which all occurrences of a specified string in the current instance are replaced with another 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 occurrances of oldValue.</param>
/// <param name="comparisonType">Type of the comparison.</param>
/// <returns></returns>
public static string Replace(this string str, string oldValue, string @newValue, StringComparison comparisonType)
{
@newValue = @newValue ?? string.Empty;
if (string.IsNullOrEmpty(str) || string.IsNullOrEmpty(oldValue) || oldValue.Equals(@newValue, comparisonType))
{
return str;
}
int foundAt;
while ((foundAt = str.IndexOf(oldValue, 0, comparisonType)) != -1)
{
str = str.Remove(foundAt, oldValue.Length).Insert(foundAt, @newValue);
}
return str;
}
확장 방법을 작성했습니다.
public static string ReplaceIgnoreCase(this string source, string oldVale, string newVale)
{
if (source.IsNullOrEmpty() || oldVale.IsNullOrEmpty())
return source;
var stringBuilder = new StringBuilder();
string result = source;
int index = result.IndexOf(oldVale, StringComparison.InvariantCultureIgnoreCase);
while (index >= 0)
{
if (index > 0)
stringBuilder.Append(result.Substring(0, index));
if (newVale.IsNullOrEmpty().IsNot())
stringBuilder.Append(newVale);
stringBuilder.Append(result.Substring(index + oldVale.Length));
result = stringBuilder.ToString();
index = result.IndexOf(oldVale, StringComparison.InvariantCultureIgnoreCase);
}
return result;
}
이전 확장 방법에는 두 가지 추가 확장 방법을 사용합니다.
public static bool IsNullOrEmpty(this string value)
{
return string.IsNullOrEmpty(value);
}
public static bool IsNot(this bool val)
{
return val == false;
}
IsNot
확장을 너무 심각하게 생각하고 있습니다 :)
.IsNot
검색 문자열에 Petrucio 의 답변을 확장 Regex.Escape
하고 Steve B 의 답변 에서 제안한대로 일치하는 그룹을 이스케이프 처리합니다 (그리고 내 취향에 약간의 변화가 있습니다).
public static class StringExtensions
{
public static string ReplaceIgnoreCase(this string str, string from, string to)
{
return Regex.Replace(str, Regex.Escape(from), to.Replace("$", "$$"), RegexOptions.IgnoreCase);
}
}
다음과 같은 예상 결과가 생성됩니다.
Console.WriteLine("(heLLo) wOrld".ReplaceIgnoreCase("(hello) world", "Hi $1 Universe")); // Hi $1 Universe
Console.WriteLine("heLLo wOrld".ReplaceIgnoreCase("(hello) world", "Hi $1 Universe")); // heLLo wOrld
그러나 이스케이프를 수행하지 않으면 다음과 같은 결과를 얻습니다. String.Replace
대소 문자를 구분하지 않는 예상 동작은 아닙니다 .
Console.WriteLine("(heLLo) wOrld".ReplaceIgnoreCase_NoEscaping("(hello) world", "Hi $1 Universe")); // (heLLo) wOrld
Console.WriteLine("heLLo wOrld".ReplaceIgnoreCase_NoEscaping("(hello) world", "Hi $1 Universe")); // Hi heLLo Universe
이 작동하지 않습니다 : 더 빠르고 쉬운 다른 것을 이미징 할 수 없습니다.
public static class ExtensionMethodsString
{
public static string Replace(this String thisString, string oldValue, string newValue, StringComparison stringComparison)
{
string working = thisString;
int index = working.IndexOf(oldValue, stringComparison);
while (index != -1)
{
working = working.Remove(index, oldValue.Length);
working = working.Insert(index, newValue);
index = index + newValue.Length;
index = working.IndexOf(oldValue, index, stringComparison);
}
return working;
}
}
아래 함수는 문자열 세트에서 (this)와 같은 모든 일치 단어를 제거하는 것입니다. Ravikant Sonare 작성
private static void myfun()
{
string mystring = "thiTHISThiss This THIS THis tThishiThiss. Box";
var regex = new Regex("this", RegexOptions.IgnoreCase);
mystring = regex.Replace(mystring, "");
string[] str = mystring.Split(' ');
for (int i = 0; i < str.Length; i++)
{
if (regex.IsMatch(str[i].ToString()))
{
mystring = mystring.Replace(str[i].ToString(), string.Empty);
}
}
Console.WriteLine(mystring);
}
@Georgy Batalov 솔루션을 사용하면 다음 예제를 사용할 때 문제가 발생했습니다
문자열 원본 = "blah, DC = bleh, DC = blih, DC = bloh, DC = com"; 교체 된 문자열 = original.ReplaceIgnoreCase ( ", DC =", ".")
아래는 그의 확장명을 다시 쓴 방법입니다
public static string ReplaceIgnoreCase(this string source, string oldVale,
string newVale)
{
if (source.IsNullOrEmpty() || oldVale.IsNullOrEmpty())
return source;
var stringBuilder = new StringBuilder();
string result = source;
int index = result.IndexOf(oldVale, StringComparison.InvariantCultureIgnoreCase);
bool initialRun = true;
while (index >= 0)
{
string substr = result.Substring(0, index);
substr = substr + newVale;
result = result.Remove(0, index);
result = result.Remove(0, oldVale.Length);
stringBuilder.Append(substr);
index = result.IndexOf(oldVale, StringComparison.InvariantCultureIgnoreCase);
}
if (result.Length > 0)
{
stringBuilder.Append(result);
}
return stringBuilder.ToString();
}
다음은 문자열 대소 문자를 무시하는 대체 방법입니다.
String thisString = "hello world";
String replaceString = "World";
//thisString.Replace("World", "csharp");
//below is the alternative to replace string ignoring character case
int start = StringUtils.indexOfIgnoreCase(thisString,replaceString);
String searchKey = thisString.substring(start, start+replaceString.length());
thisString= thisString.replaceAll(searchKey ,replaceString );
System.out.println(thisString);
//prints hello World
나는 이것을 선호한다- "Hello World".ToLower (). Replace ( "world", "csharp");