visual todas solo sea que primera poner net minusculas minuscula mayusculas mayuscula letra hacer convertir cambiar c# .net string .net-2.0 replace

c# - todas - ¿Existe una alternativa a la cadena? ¿Reemplazar que no distinga mayúsculas y minúsculas?



solo mayuscula vb net (15)

(Ya que todos están tomando una oportunidad en esto). Aquí está mi versión (con chequeos nulos y escape de entrada y reemplazo correctos) ** Inspirado en Internet y otras versiones:

using System; using System.Text.RegularExpressions; public static class MyExtensions { public static string ReplaceIgnoreCase(this string search, string find, string replace) { return Regex.Replace(search ?? "", Regex.Escape(find ?? ""), (replace ?? "").Replace("$", "$$"), RegexOptions.IgnoreCase); } }

Uso:

var result = "This is a test".ReplaceIgnoreCase("IS", "was");

Necesito buscar una cadena y reemplazar todas las apariciones de %FirstName% y %PolicyAmount% con un valor extraído de una base de datos. El problema es que las mayúsculas de FirstName varían. Eso me impide usar el método String.Replace() . He visto páginas web sobre el tema que sugieren.

Regex.Replace(strInput, strToken, strReplaceWith, RegexOptions.IgnoreCase);

Sin embargo, por alguna razón, cuando trato de reemplazar %PolicyAmount% con $0 , el reemplazo nunca tiene lugar. Supongo que tiene algo que ver con que el signo de dólar sea un carácter reservado en expresiones regulares.

¿Hay otro método que pueda usar que no implique la limpieza de la entrada para tratar con los caracteres especiales de expresiones regulares?


Ampliando la popular respuesta de C. Dragon 76 al convertir su código en una extensión que sobrecarga el método de Replace predeterminado.

public static class StringExtensions { public static string Replace(this string str, string oldValue, string newValue, StringComparison comparison) { StringBuilder sb = new StringBuilder(); int previousIndex = 0; int index = str.IndexOf(oldValue, comparison); while (index != -1) { sb.Append(str.Substring(previousIndex, index - previousIndex)); sb.Append(newValue); index += oldValue.Length; previousIndex = index; index = str.IndexOf(oldValue, index, comparison); } sb.Append(str.Substring(previousIndex)); return sb.ToString(); } }


Aquí hay otra opción para ejecutar reemplazos de Regex, ya que no muchas personas parecen notar que las coincidencias contienen la ubicación dentro de la cadena:

public static string ReplaceCaseInsensative( this string s, string oldValue, string newValue ) { var sb = new StringBuilder(s); int offset = oldValue.Length - newValue.Length; int matchNo = 0; foreach (Match match in Regex.Matches(s, Regex.Escape(oldValue), RegexOptions.IgnoreCase)) { sb.Remove(match.Index - (offset * matchNo), match.Length).Insert(match.Index - (offset * matchNo), newValue); matchNo++; } return sb.ToString(); }


Aquí hay un método de extensión. No estoy seguro de donde lo encontré.

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


Basado en la respuesta de Jeff Reddy, con algunas optimizaciones y validaciones:

public static string Replace(string str, string oldValue, string newValue, StringComparison comparison) { if (oldValue == null) throw new ArgumentNullException("oldValue"); if (oldValue.Length == 0) throw new ArgumentException("String cannot be of zero length.", "oldValue"); StringBuilder sb = null; int startIndex = 0; int foundIndex = str.IndexOf(oldValue, comparison); while (foundIndex != -1) { if (sb == null) sb = new StringBuilder(str.Length + (newValue != null ? Math.Max(0, 5 * (newValue.Length - oldValue.Length)) : 0)); sb.Append(str, startIndex, foundIndex - startIndex); sb.Append(newValue); startIndex = foundIndex + oldValue.Length; foundIndex = str.IndexOf(oldValue, startIndex, comparison); } if (startIndex == 0) return str; sb.Append(str, startIndex, str.Length - startIndex); return sb.ToString(); }


Déjame hacer mi caso y luego puedes romperme en pedazos si quieres.

Regex no es la respuesta para este problema: demasiado lento y con hambre de memoria, relativamente hablando.

StringBuilder es mucho mejor que la manipulación de cadenas.

Dado que este será un método de extensión para complementar la string.Replace . string.Replace , creo que es importante que coincida con el modo en que funciona, por lo tanto, es importante lanzar excepciones para los mismos problemas de argumentos, ya que se devuelve la cadena original si no se hizo un reemplazo.

Creo que tener un parámetro StringComparison no es una buena idea. Lo intenté, pero el caso de prueba originalmente mencionado por michael-liu mostró un problema:

[TestCase("œ", "oe", "", StringComparison.InvariantCultureIgnoreCase, Result = "")]

Mientras que IndexOf coincidirá, existe una discrepancia entre la longitud de la coincidencia en la cadena de origen (1) y oldValue.Length (2). Esto se manifestó al causar IndexOutOfRange en algunas otras soluciones cuando se agregó oldValue.Length a la posición de coincidencia actual y no pude encontrar una manera de evitar esto. Regex no coincide con el caso de todos modos, así que tomé la solución pragmática de solo usar StringComparison.OrdinalIgnoreCase para mi solución.

Mi código es similar a otras respuestas, pero mi giro es que busco una coincidencia antes de tomarme la molestia de crear un StringBuilder . Si no se encuentra ninguno, se evita una asignación potencialmente grande. El código se convierte en un do{...}while que en un while{...}

He realizado algunas pruebas exhaustivas con otras Respuestas y esto salió ligeramente más rápido y usé un poco menos de memoria.

public static string ReplaceCaseInsensitive(this string str, string oldValue, string newValue) { if (str == null) throw new ArgumentNullException(nameof(str)); if (oldValue == null) throw new ArgumentNullException(nameof(oldValue)); if (oldValue.Length == 0) throw new ArgumentException("String cannot be of zero length.", nameof(oldValue)); var position = str.IndexOf(oldValue, 0, StringComparison.OrdinalIgnoreCase); if (position == -1) return str; var sb = new StringBuilder(str.Length); var lastPosition = 0; do { sb.Append(str, lastPosition, position - lastPosition); sb.Append(newValue); } while ((position = str.IndexOf(oldValue, lastPosition = position + oldValue.Length, StringComparison.OrdinalIgnoreCase)) != -1); sb.Append(str, lastPosition, str.Length - lastPosition); return sb.ToString(); }


El método de expresión regular debería funcionar. Sin embargo, lo que también puede hacer es minúscula la cadena de la base de datos, minúscula el% variables% que tiene, y luego ubicar las posiciones y longitudes en la cadena de la base inferior. Recuerda, las posiciones en una cadena no cambian solo porque está encajonada.

Luego, utilizando un bucle que va en sentido inverso (es más fácil, si no lo hace, tendrá que mantener un recuento continuo de los puntos a los que se moverán más adelante) eliminar de su cadena no inferior de la base de datos el% variable% por su posición y Longitud e insertar los valores de reemplazo.


Inspirado por la respuesta de cfeduke, hice esta función que usa IndexOf para encontrar el valor antiguo en la cadena y luego lo reemplaza con el nuevo valor. Utilicé esto en un script SSIS que procesaba millones de filas, y el método regex era mucho más lento que esto.

public static string ReplaceCaseInsensitive(this string str, string oldValue, string newValue) { int prevPos = 0; string retval = str; // find the first occurence of oldValue int pos = retval.IndexOf(oldValue, StringComparison.InvariantCultureIgnoreCase); while (pos > -1) { // remove oldValue from the string retval = retval.Remove(pos, oldValue.Length); // insert newValue in it''s place retval = retval.Insert(pos, newValue); // check if oldValue is found further down prevPos = pos + newValue.Length; pos = retval.IndexOf(oldValue, prevPos, StringComparison.InvariantCultureIgnoreCase); } return retval; }


Parece que string.Replace debería tener una sobrecarga que tome un argumento StringComparison . Como no es así, puedes probar algo como esto:

public static string ReplaceString(string str, string oldValue, string newValue, StringComparison comparison) { StringBuilder sb = new StringBuilder(); int previousIndex = 0; int index = str.IndexOf(oldValue, comparison); while (index != -1) { sb.Append(str.Substring(previousIndex, index - previousIndex)); sb.Append(newValue); index += oldValue.Length; previousIndex = index; index = str.IndexOf(oldValue, index, comparison); } sb.Append(str.Substring(previousIndex)); return sb.ToString(); }


Parece que el método más sencillo es simplemente usar el método Reemplazar que se envía con .Net y ha existido desde .Net 1.0:

string res = Microsoft.VisualBasic.Strings.Replace(res, "%PolicyAmount%", "$0", Compare: Microsoft.VisualBasic.CompareMethod.Text);

Para utilizar este método, debe agregar una referencia al conjunto de Microsoft.VisualBasic. Este ensamblaje es una parte estándar del tiempo de ejecución .Net, no es una descarga adicional o está marcado como obsoleto.


Una especie de grupo de respuestas confuso, en parte porque el título de la pregunta es en realidad mucho más grande que la pregunta específica que se formula. Después de leerlo, no estoy seguro de que alguna respuesta esté a algunas ediciones de asimilar todas las cosas buenas aquí, así que pensé que intentaría sumar.

Aquí hay un método de extensión que creo que evita los escollos mencionados aquí y proporciona la solución más ampliamente aplicable.

public static string ReplaceCaseInsensitiveFind(this string str, string findMe, string newValue) { return Regex.Replace(str, Regex.Escape(findMe), Regex.Replace(newValue, "//$[0-9]+", @"$$$0"), RegexOptions.IgnoreCase); }

Asi que...

Desafortunadamente, el comentario de @HA de que tienes que Escape los tres no es correcto . El valor inicial y newValue no necesitan ser.

Nota: Sin embargo, tiene que escapar $ s en el nuevo valor que está insertando si son parte de lo que parece ser un marcador de "valor capturado" . Por lo tanto, los tres signos de dólar en el Regex. Reemplace dentro del Regex. Reemplace [sic] Sin eso, algo como esto se rompe ...

"This is HIS fork, hIs spoon, hissssssss knife.".ReplaceCaseInsensitiveFind("his", @"he$0r")

Aquí está el error:

An unhandled exception of type ''System.ArgumentException'' occurred in System.dll Additional information: parsing "The/hisr/ is/ he/HISr/ fork,/ he/hIsr/ spoon,/ he/hisrsssssss/ knife/." - Unrecognized escape sequence /h.

Sé que las personas que se sienten cómodas con Regex sienten que su uso evita los errores, pero a menudo todavía soy parcial a las cadenas de sniffing de bytes (pero solo después de haber leído Spolsky en las codificaciones ) para estar absolutamente seguro de que está obteniendo lo que usted necesita. destinado a casos de uso importantes. Me recuerda a Crockford en " expresiones regulares inseguras " un poco. Con demasiada frecuencia escribimos expresiones regulares que permiten lo que queremos (si tenemos suerte), pero sin intención permitimos más entradas (por ejemplo, ¿Es $10 realmente una cadena válida de "valor de captura" en mi nueva expresión regular de valores, arriba?) Porque no fuimos conscientes suficiente. Ambos métodos tienen valor, y ambos fomentan diferentes tipos de errores involuntarios. A menudo es fácil subestimar la complejidad.

Esa extraña fuga de $ (y que Regex.Escape no escapó a los patrones de valor capturados como $0 como hubiera esperado en valores de reemplazo) me enloqueció por un tiempo. La programación es difícil (c) 1842


una versión similar a la de C. Dragon, pero si solo necesita un reemplazo:

int n = myText.IndexOf(oldValue, System.StringComparison.InvariantCultureIgnoreCase); if (n >= 0) { myText = myText.Substring(0, n) + newValue + myText.Substring(n + oldValue.Length); }


Desde MSDN
$ 0 - "Sustituye la última subcadena que coincide con el número de grupo (decimal)".

En .NET, el grupo de expresiones regulares 0 es siempre la coincidencia completa. Para un $ literal necesitas

string value = Regex.Replace("%PolicyAmount%", "%PolicyAmount%", @"$$0", RegexOptions.IgnoreCase);


/// <summary> /// A case insenstive replace function. /// </summary> /// <param name="originalString">The string to examine.(HayStack)</param> /// <param name="oldValue">The value to replace.(Needle)</param> /// <param name="newValue">The new value to be inserted</param> /// <returns>A string</returns> public static string CaseInsenstiveReplace(string originalString, string oldValue, string newValue) { Regex regEx = new Regex(oldValue, RegexOptions.IgnoreCase | RegexOptions.Multiline); return regEx.Replace(originalString, newValue); }


Regex.Replace(strInput, strToken.Replace("$", "[$]"), strReplaceWith, RegexOptions.IgnoreCase);