visual valid tag name method example documentacion comment comentarios c# string

valid - tag c#



Cadena.Remplazar caso ignorante (13)

¿Esto no funciona? No puedo visualizar nada más rápido o más fácil.

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; } }

Tengo una cadena llamada "hola mundo"

Necesito reemplazar la palabra "mundo" por "csharp"

para esto uso:

string.Replace("World", "csharp");

pero como resultado, no reemplazo la cadena. La razón es sensibilidad a las mayúsculas y minúsculas. La cadena original contiene "mundo" mientras que estoy tratando de reemplazar "Mundo".

¿Hay alguna manera de evitar esta sensibilidad a mayúsculas y minúsculas en la cadena? ¿Reemplazar el método?


( Editado: no estaba al tanto del problema del "enlace desnudo", lo siento)

Tomado desde here :

string myString = "find Me and replace ME"; string strReplace = "me"; myString = Regex.Replace(myString, "me", strReplace, RegexOptions.IgnoreCase);

Parece que no eres el primero en quejarse de la falta de cadena insensible a mayúsculas y minúsculas. Reemplaza.


Ampliando la respuesta de Regex.Escape con Regex.Escape en la cadena de búsqueda, y escapando del grupo coincidente como se sugiere en la respuesta de (y algunos cambios menores en mi gusto):

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); } }

Lo cual producirá los siguientes resultados esperados:

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

Sin embargo, sin realizar los escapes obtendría lo siguiente, que no es un comportamiento esperado de un String.Replace que no distingue entre mayúsculas y minúsculas:

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


He escrito el método de extensión:

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; }

Utilizo dos métodos de extensión adicionales para el método de extensión anterior:

public static bool IsNullOrEmpty(this string value) { return string.IsNullOrEmpty(value); } public static bool IsNot(this bool val) { return val == false; }


La función siguiente es eliminar todas las palabras coincidentes como (esto) del conjunto de cadenas. Por 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); }


La respuesta de @ Darky711 modificada para usar el tipo aprobado en comparación y coincidir con el marco reemplaza el nombre y los comentarios xml lo más cerca posible.

/// <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; }


Las extensiones nos hacen la vida más fácil:

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; } }


Muchas sugerencias usando Regex. ¿Qué tal este método de extensión sin él?

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; }


Podría usar un Regex y realizar un reemplazo insensible a mayúsculas y minúsculas:

class Program { static void Main() { string input = "hello WoRlD"; string result = Regex.Replace(input, "world", "csharp", RegexOptions.IgnoreCase); Console.WriteLine(result); // prints "hello csharp" } }


Puede usar el espacio de nombres Microsoft.VisualBasic para encontrar esta función auxiliar:

Replace(sourceString, "replacethis", "withthis", , , CompareMethod.Text)


Usando la solución de @Georgy Batalov tuve un problema al usar el siguiente ejemplo

cadena original = "bla, DC = bleh, DC = blih, DC = bloh, DC = com"; cadena reemplazada = original.ReplaceIgnoreCase (", DC =", ".")

A continuación se muestra cómo reescribí su extensión

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(); }


2.5 veces MÁS RÁPIDO y MÁS EFECTIVO que otros métodos de expresiones regulares:

/// <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(); }

Nota: ignore case == StringComparison.OrdinalIgnoreCase como parámetro para StringComparison comparisonType . Es la manera más rápida, insensible a mayúsculas y minúsculas de reemplazar todos los valores.

Ventajas de este método:

  • Alta CPU y eficiencia de MEMORIA;
  • Es la solución más rápida, 2.5 veces más rápida que los métodos de otros con expresiones regulares (prueba al final);
  • Adecuado para eliminar partes de la cadena de entrada (establecer newValue en null ), optimizado para esto;
  • Igual que la string.Replace .NET C # original . string.Replace comportamiento, mismas excepciones;
  • Bien comentado, fácil de entender;
  • Más simple: sin expresiones regulares. Las expresiones regulares son siempre más lentas debido a su versatilidad (incluso compilada);
  • Este método está bien probado y no hay fallas ocultas como bucle infinito en las soluciones de otros, incluso altamente calificadas:

@AsValeO: no funciona con elementos de lenguaje Regex, por lo que no es un método universal

@Mike Stillion: hay un problema con este código. Si el texto en new es un superconjunto del texto en old, esto puede producir un bucle infinito.

Benchmark-proof : esta solución es 2.59 veces más rápida que la expresión regular de @Steve B., código:

// 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();

Idea original - @ Darky711; gracias @MinerR para StringBuilder .


var search = "world"; var replacement = "csharp"; string result = Regex.Replace( stringToLookInto, Regex.Escape(search), replacement.Replace("$","$$"), RegexOptions.IgnoreCase );

El Regex.Escape es útil si Regex.Escape en la entrada del usuario que puede contener elementos del lenguaje Regex

Actualizar

Gracias a los comentarios, en realidad no tiene que escapar de la cadena de reemplazo.

Aquí hay un pequeño violín que prueba el código :

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; } }

Su salida es:

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 }