2011-05-26 14 views
48

necesito una manera de tener presente:manera de tener éxito "String.Replace solamente palabras completas"

"test, and test but not testing. But yes to test".Replace("test", "text") 

de regreso este:

"text, and text but not testing. But yes to text" 

Básicamente quiero reemplazar palabras completas, pero no coincidencias parciales.

NOTA: Voy a tener que usar VB para esto (código de SSRS 2008), pero C# es mi lenguaje normal, por lo que las respuestas en cualquiera de ellas están bien.

+0

Puede Usas un Reg ¿Ex? – Gabe

+0

Esto está duplicado aquí. Creo que: http://stackoverflow.com/questions/1209049/regex-match-welf-words –

+0

Supongo que la manera más fácil (posiblemente no sea la mejor) sería agregar un espacio al principio y fin del término de búsqueda, por ejemplo, para reemplazar palabras enteras, busque: "ahogarse" para que no reemplace cosas como "ahogamiento". –

Respuesta

77

una expresión regular es el método más sencillo:

string input = "test, and test but not testing. But yes to test"; 
string pattern = @"\btest\b"; 
string replace = "text"; 
string result = Regex.Replace(input, pattern, replace); 
Console.WriteLine(result); 

La parte importante del patrón es el metacarácter \b, que coincide con los límites de palabras. Si necesita que sea sensible a las mayúsculas uso RegexOptions.IgnoreCase:

Regex.Replace(input, pattern, replace, RegexOptions.IgnoreCase); 
+10

Donde '\ b' es expresiones regulares para los límites de las palabras. – Oded

+1

¡Su solución es genial! Si muchos publican un contenedor fn con el escape de expresiones regulares: 'cadena estática ReplaceFullWords (entrada de cadena, cadena de, cadena a) {if (entrada == nulo) {return null; } return Regex.Replace (entrada, "\\ b" + Regex.Escape (desde) + "\\ b", a); } ' – ZTK

+0

https://www.regular-expressions.info/wordboundaries.html – BenG

15

He creado una función (ver blog post here) que envuelve la expresión expresiones regulares, sugerido por Ahmad Mageed

/// <summary> 
/// Uses regex '\b' as suggested in https://stackoverflow.com/questions/6143642/way-to-have-string-replace-only-hit-whole-words 
/// </summary> 
/// <param name="original"></param> 
/// <param name="wordToFind"></param> 
/// <param name="replacement"></param> 
/// <param name="regexOptions"></param> 
/// <returns></returns> 
static public string ReplaceWholeWord(this string original, string wordToFind, string replacement, RegexOptions regexOptions = RegexOptions.None) 
{ 
    string pattern = String.Format(@"\b{0}\b", wordToFind); 
    string ret=Regex.Replace(original, pattern, replacement, regexOptions); 
    return ret; 
} 
+1

Recuerde usar' Regex.Escape() 'en' wordToFind' para que los caracteres especiales se interpreten como caracteres normales. – CheeseSucker

3

Sólo quiero añadir una tenga en cuenta este patrón de expresiones regulares particular (utilizado tanto en la respuesta aceptada como en la función ReplaceWholeWord). No funciona si lo que está tratando de reemplazar no es una palabra .

aquí un caso de prueba:

using System; 
using System.Text.RegularExpressions; 
public class Test 
{ 
    public static void Main() 
    { 
     string input = "doin' some replacement"; 
     string pattern = @"\bdoin'\b"; 
     string replace = "doing"; 
     string result = Regex.Replace(input, pattern, replace); 
     Console.WriteLine(result); 
    } 
} 

(listo para probar código: http://ideone.com/2Nt0A)

Esto tiene que ser tenido en cuenta especialmente si usted está haciendo traducciones de lote (como lo hice para un trabajo i18n)

+0

Se espera. "Doin '" no es una "palabra completa". Está intentando reemplazar "subcadenas separadas por espacios en blanco" –

7

Como comentó Sga, la solución de expresiones regulares no es perfecta. Y supongo que no es muy amigable para el rendimiento.

Aquí es mi contribución:

public static class StringExtendsionsMethods 
{ 
    public static String ReplaceWholeWord (this String s, String word, String bywhat) 
    { 
     char firstLetter = word[0]; 
     StringBuilder sb = new StringBuilder(); 
     bool previousWasLetterOrDigit = false; 
     int i = 0; 
     while (i < s.Length - word.Length + 1) 
     { 
      bool wordFound = false; 
      char c = s[i]; 
      if (c == firstLetter) 
       if (! previousWasLetterOrDigit) 
        if (s.Substring (i, word.Length).Equals (word)) 
        { 
         wordFound = true; 
         bool wholeWordFound = true; 
         if (s.Length > i + word.Length) 
         { 
          if (Char.IsLetterOrDigit (s[i+word.Length])) 
           wholeWordFound = false; 
         } 

         if (wholeWordFound) 
          sb.Append (bywhat); 
         else 
          sb.Append (word); 

         i += word.Length; 
        } 

      if (! wordFound) 
      { 
       previousWasLetterOrDigit = Char.IsLetterOrDigit (c); 
       sb.Append (c); 
       i++; 
      } 
     } 

     if (s.Length - i > 0) 
      sb.Append (s.Substring (i)); 

     return sb.ToString(); 
    } 
} 

... Con casos de prueba:

String a = "alpha is alpha"; 
Console.WriteLine (a.ReplaceWholeWord ("alpha", "alphonse")); 
Console.WriteLine (a.ReplaceWholeWord ("alpha", "alf")); 

a = "alphaisomega"; 
Console.WriteLine (a.ReplaceWholeWord ("alpha", "xxx")); 

a = "aalpha is alphaa"; 
Console.WriteLine (a.ReplaceWholeWord ("alpha", "xxx")); 

a = "alpha1/alpha2/alpha3"; 
Console.WriteLine (a.ReplaceWholeWord ("alpha", "xxx")); 

a = "alpha/alpha/alpha"; 
Console.WriteLine (a.ReplaceWholeWord ("alpha", "alphonse")); 
+0

@Alexis, debe cambiar el nombre de la función como ReplaceWhitespaceSeparatedSubstrings. Además, proporcione el comentario de salida esperado para cada caso de prueba. Si realizó alguna comparación de rendimiento con el enfoque de expresión regular, compártalo. –

+0

Simplemente ejecute los casos de prueba para ver los resultados de salida. –

+1

Esto no es un 'espacio en blanco separado' sino una 'cualquier char, no una letra o número' separado. No, no hice comparaciones de perf. –

-1

código C# (aplicación de consola)

programa de clase

{ 
    static void Main(string[] args) 
    { 
     Console.Write("Please input your comment: "); 
     string str = Console.ReadLine(); 
     string[] str2 = str.Split(' '); 
     replaceStringWithString(str2); 
     Console.ReadLine(); 
    } 
    public static void replaceStringWithString(string[] word) 
    { 
     string[] strArry1 = new string[] { "good", "bad", "hate" }; 
     string[] strArry2 = new string[] { "g**d", "b*d", "h**e" }; 
     for (int j = 0; j < strArry1.Count(); j++) 
     { 
      for (int i = 0; i < word.Count(); i++) 
      { 
       if (word[i] == strArry1[j]) 
       { 
        word[i] = strArry2[j]; 
       } 
       Console.Write(word[i] + " "); 
      } 
     } 
    } 
} 
Cuestiones relacionadas