Reemplazar varios caracteres en una cadena C #

¿Hay una mejor manera de reemplazar cadenas?

Me sorprende que Replace no tome una matriz de caracteres o una matriz de cadenas. Supongo que podría escribir mi propia extensión, pero tenía curiosidad de saber si existe una mejor manera de hacer lo siguiente. Observe que el último reemplazo es una cadena, no un personaje.

myString.Replace(';', '\n').Replace(',', '\n').Replace('\r', '\n').Replace('\t', '\n').Replace(' ', '\n').Replace("\n\n", "\n"); 

Puede usar una expresión regular de reemplazo.

 s/[;,\t\r ]|[\n]{2}/\n/g 
  • s/ al comienzo significa una búsqueda
  • Los caracteres entre [ y ] son los caracteres a buscar (en cualquier orden)
  • El segundo / delimita el texto de búsqueda y el texto de reemplazo

En inglés, esto dice:

“Buscar ; o , o \t o \r o (espacio) o exactamente dos \n secuencial y reemplazarlo por \n

En C #, podría hacer lo siguiente: (después de importar System.Text.RegularExpressions )

 Regex pattern = new Regex("[;,\t\r ]|[\n]{2}"); pattern.Replace(myString, "\n"); 

Si te sientes especialmente inteligente y no quieres usar Regex:

 char[] separators = new char[]{' ',';',',','\r','\t','\n'}; string s = "this;is,\ra\t\n\n\ntest"; string[] temp = s.Split(separators, StringSplitOptions.RemoveEmptyEntries); s = String.Join("\n", temp); 

Podría envolver esto en un método de extensión con muy poco esfuerzo también.

Editar: O simplemente espera 2 minutos y terminaré escribiéndolo de todos modos 🙂

 public static class ExtensionMethods { public static string Replace(this string s, char[] separators, string newVal) { string[] temp; temp = s.Split(separators, StringSplitOptions.RemoveEmptyEntries); return String.Join( newVal, temp ); } } 

Y voilá…

 char[] separators = new char[]{' ',';',',','\r','\t','\n'}; string s = "this;is,\ra\t\n\n\ntest"; s = s.Replace(separators, "\n"); 

Podría usar la función Agregado de Linq:

 string s = "the\nquick\tbrown\rdog,jumped;over the lazy fox."; char[] chars = new char[] { ' ', ';', ',', '\r', '\t', '\n' }; string snew = chars.Aggregate(s, (c1, c2) => c1.Replace(c2, '\n')); 

Aquí está el método de extensión:

 public static string ReplaceAll(this string seed, char[] chars, char replacementCharacter) { return chars.Aggregate(seed, (str, cItem) => str.Replace(cItem, replacementCharacter)); } 

Esta es la forma más corta:

 myString = Regex.Replace(myString, @"[;,\t\r ]|[\n]{2}", "\n"); 

Ohhh, el horror de rendimiento! La respuesta está un poco desactualizada, pero aún así …

 public static class StringUtils { #region Private members [ThreadStatic] private static StringBuilder m_ReplaceSB; private static StringBuilder GetReplaceSB(int capacity) { var result = m_ReplaceSB; if (null == result) { result = new StringBuilder(capacity); m_ReplaceSB = result; } else { result.Clear(); result.EnsureCapacity(capacity); } return result; } public static string ReplaceAny(this string s, char replaceWith, params char[] chars) { if (null == chars) return s; if (null == s) return null; StringBuilder sb = null; for (int i = 0, count = s.Length; i < count; i++) { var temp = s[i]; var replace = false; for (int j = 0, cc = chars.Length; j < cc; j++) if (temp == chars[j]) { if (null == sb) { sb = GetReplaceSB(count); if (i > 0) sb.Append(s, 0, i); } replace = true; break; } if (replace) sb.Append(replaceWith); else if (null != sb) sb.Append(temp); } return null == sb ? s : sb.ToString(); } } 

Las cadenas son solo matrices de caracteres inmutables

Solo necesitas hacerlo mutable:

  • ya sea usando StringBuilder
  • entrar en el mundo unsafe y jugar con punteros (aunque peligroso)

y tratar de iterar a través de la matriz de caracteres la menor cantidad de veces.

Ejemplo con StringBuilder

  public static void MultiReplace(this StringBuilder builder, char[] toReplace, char replacement) { HashSet set = new HashSet(toReplace); for (int i = 0; i < builder.Length; ++i) { var currentCharacter = builder[i]; if (set.Contains(currentCharacter)) { builder[i] = replacement; } } } 

Entonces solo tienes que usarlo así:

 var builder = new StringBuilder("my bad,url&slugs"); builder.MultiReplace(new []{' ', '&', ','}, '-'); var result = builder.ToString(); 

Use RegEx.Replace, algo como esto:

  string input = "This is text with far too much " + "whitespace."; string pattern = "[;,]"; string replacement = "\n"; Regex rgx = new Regex(pattern); 

Aquí hay más información sobre esta documentación de MSDN para RegEx.Replace

Desempeño-Sabio, probablemente esta no sea la mejor solución, pero funciona.

 var str = "filename:with&bad$separators.txt"; char[] charArray = new char[] { '#', '%', '&', '{', '}', '\\', '<', '>', '*', '?', '/', ' ', '$', '!', '\'', '"', ':', '@' }; foreach (var singleChar in charArray) { str = str.Replace(singleChar, '_'); } 

También puede simplemente escribir estos métodos de extensión de cadena y ponerlos en algún lugar de su solución:

 using System.Text; public static class StringExtensions { public static string ReplaceAll(this string original, string toBeReplaced, string newValue) { if (string.IsNullOrEmpty(original) || string.IsNullOrEmpty(toBeReplaced)) return original; if (newValue == null) newValue = string.Empty; StringBuilder sb = new StringBuilder(); foreach (char ch in original) { if (toBeReplaced.IndexOf(ch) < 0) sb.Append(ch); else sb.Append(newValue); } return sb.ToString(); } public static string ReplaceAll(this string original, string[] toBeReplaced, string newValue) { if (string.IsNullOrEmpty(original) || toBeReplaced == null || toBeReplaced.Length <= 0) return original; if (newValue == null) newValue = string.Empty; foreach (string str in toBeReplaced) if (!string.IsNullOrEmpty(str)) original = original.Replace(str, newValue); return original; } } 

Llámalos así:

 "ABCDE".ReplaceAll("ACE", "xy"); 

xyBxyDxy

Y esto:

 "ABCDEF".ReplaceAll(new string[] { "AB", "DE", "EF" }, "xy"); 

xyCxyF

  string FileName = "filename;with _forbiddenChars = new List(); _forbiddenChars.Add("?"); _forbiddenChars.Add("<"); _forbiddenChars.Add(">"); _forbiddenChars.Add(":"); _forbiddenChars.Add("|"); _forbiddenChars.Add("\\"); _forbiddenChars.Add("/"); _forbiddenChars.Add("*"); _forbiddenChars.Add(";"); for (int i = 0; i < _forbiddenChars.Count; i++) { FileName = FileName.Replace(_forbiddenChars[i], ""); }