83 votes

Manière d'avoir String.Replace seulement frappé "mots entiers"

J'ai besoin d'un moyen d'avoir ceci:

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

retourne ceci:

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

En gros, je veux remplacer les mots entiers, mais pas les correspondances partielles.

Remarque: je vais devoir utiliser VB pour cela (code 2008 SSRS), mais C # est mon langage normal, donc les réponses dans les deux sont correctes.

140voto

Ahmad Mageed Points 44495

Une expression régulière est l'approche la plus simple:

 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 partie importante du motif est le métacaractère \b , qui correspond aux limites des mots. Si vous en avez besoin, faites une utilisation insensible à la casse RegexOptions.IgnoreCase :

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

24voto

Michael Freidgeim Points 4002

J'ai créé une fonction (voir l' article du blog ici ) qui enveloppe l'expression rationnelle, suggérée par Ahmad Mageed

 /// <summary>
    /// Uses regex '\b' as suggested in //http://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;
        }
 

8voto

Alexis Pautrot Points 325

Comme l'a commenté Sga, la solution regex n'est pas parfaite. Et je suppose que la performance n’est pas aussi favorable

Voici ma contribution:

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

... avec des cas de test:

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

6voto

Sga Points 1293

Je veux juste ajouter une remarque à propos de cette expression régulière pattern (utilisé à la fois dans l'acceptation de réponse et dans ReplaceWholeWordfonction). Il ne fonctionne pas si ce que vous essayez de remplacer n'est pas un mot.

Ici, un cas de test:

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

(prêt à essayer de code: http://ideone.com/2Nt0A)

Ceci doit être pris en considération, surtout si vous faites un lot de traductions (comme je l'ai fait pour certains i18n travail).

0voto

Anonymous Points 3

Code C # (application console)

programme de classe

 {
    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] + " ");
            }
        }
    }
}
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X