Remplacer plusieurs éléments de chaîne en C#

y a-t-il une meilleure façon de le faire...

MyString.Trim().Replace("&", "and").Replace(",", "").Replace("  ", " ")
         .Replace(" ", "-").Replace("'", "").Replace("/", "").ToLower();

j'ai étendu la classe string à un seul travail, mais y a-t-il un moyen plus rapide?

public static class StringExtension
{
    public static string clean(this string s)
    {
        return s.Replace("&", "and").Replace(",", "").Replace("  ", " ")
                .Replace(" ", "-").Replace("'", "").Replace(".", "")
                .Replace("eacute;", "é").ToLower();
    }
}

Juste pour le fun (et pour arrêter les arguments dans les commentaires) J'ai poussé un résumé analyse comparative les différents exemples ci-dessous.

https://gist.github.com/ChrisMcKee/5937656

l'option regex marque terriblement; l'option dictionary est la plus rapide; la version longue winded du remplacement stringbuilder est légèrement plus rapide que la main courte.

63
demandé sur Chris McKee 2009-08-24 13:25:04

8 réponses

plus rapide-no. Plus efficace - Oui, si vous utilisez la classe StringBuilder . Avec votre implémentation, chaque opération génère une copie d'une chaîne de caractères qui, dans certaines circonstances, peut nuire aux performances. Les chaînes sont des objets immuables donc chaque opération renvoie une copie modifiée.

si vous vous attendez à ce que cette méthode soit activement appelée Sur le multiple Strings de longueur significative, il pourrait être préférable de "migrer" sa mise en œuvre sur le StringBuilder de la classe. Avec elle toute modification est effectuée directement sur cette instance, de sorte que vous épargnez les opérations de copie inutiles.

public static class StringExtention
{
    public static string clean(this string s)
    {
        StringBuilder sb = new StringBuilder (s);

        sb.Replace("&", "and");
        sb.Replace(",", "");
        sb.Replace("  ", " ");
        sb.Replace(" ", "-");
        sb.Replace("'", "");
        sb.Replace(".", "");
        sb.Replace("eacute;", "é");

        return sb.ToString().ToLower();
    }
}
89
répondu BC2 2013-07-12 21:45:06

Peut-être un peu plus lisible?

    public static class StringExtension {

        private static Dictionary<string, string> _replacements = new Dictionary<string, string>();

        static StringExtension() {
            _replacements["&"] = "and";
            _replacements[","] = "";
            _replacements["  "] = " ";
            // etc...
        }

        public static string clean(this string s) {
            foreach (string to_replace in _replacements.Keys) {
                s = s.Replace(to_replace, _replacements[to_replace]);
            }
            return s;
        }
    }

ajoute aussi du nouveau dans la suggestion de la ville sur StringBuilder...

10
répondu Paolo Tedesco 2013-07-12 21:30:27

ce sera plus efficace:

public static class StringExtension
{
    public static string clean(this string s)
    {
        return new StringBuilder(s)
              .Replace("&", "and")
              .Replace(",", "")
              .Replace("  ", " ")
              .Replace(" ", "-")
              .Replace("'", "")
              .Replace(".", "")
              .Replace("eacute;", "é")
              .ToString()
              .ToLower();
    }
}
8
répondu TheVillageIdiot 2017-06-16 07:51:53

si vous êtes simplement après une jolie solution et que vous n'avez pas besoin d'économiser quelques nanosecondes, Que diriez-vous D'un peu de LINQ sugar?

var input = "test1test2test3";
var replacements = new Dictionary<string, string> { { "1", "*" }, { "2", "_" }, { "3", "&" } };

var output = replacements.Aggregate(input, (current, replacement) => current.Replace(replacement.Key, replacement.Value));
6
répondu TimS 2014-05-06 02:21:38

il y a une chose qui peut être optimisée dans les solutions proposées. Avoir de nombreux appels à Replace() rend le code pour faire plusieurs passes au-dessus de la même chaîne. Avec des chaînes très longues, les solutions peuvent être lentes à cause des erreurs de capacité de cache CPU. Peut-être un devrait envisager remplacer plusieurs chaînes en un seul passage .

3
répondu Andrej Adamenko 2014-05-21 13:21:26

une autre option utilisant linq est

[TestMethod]
public void Test()
{
  var input = "it's worth a lot of money, if you can find a buyer.";
  var expected = "its worth a lot of money if you can find a buyer";
  var removeList = new string[] { ".", ",", "'" };
  var result = input;

  removeList.ToList().ForEach(o => result = result.Replace(o, string.Empty));

  Assert.AreEqual(expected, result);
}
2
répondu Luiz Felipe 2017-11-10 12:08:06

je fais quelque chose de similaire, mais dans mon cas je fais de la sérialisation/dé-sérialisation donc je dois pouvoir aller dans les deux directions. Je trouve que l'utilisation d'une chaîne de caractères[][] fonctionne presque de façon identique au dictionnaire, y compris l'initialisation, mais vous pouvez aller dans l'autre direction aussi, en retournant les substituts à leurs valeurs originales, quelque chose que le dictionnaire n'est pas vraiment mis en place pour faire.

Edit: Vous pouvez utiliser Dictionary<Key,List<Values>> pour obtenir le même résultat que la chaîne[][]

1
répondu sidDemure 2011-12-22 19:49:32
string input = "it's worth a lot of money, if you can find a buyer.";
for (dynamic i = 0, repl = new string[,] { { "'", "''" }, { "money", "$" }, { "find", "locate" } }; i < repl.Length / 2; i++) {
    input = input.Replace(repl[i, 0], repl[i, 1]);
}
-1
répondu user7718176 2017-03-16 00:23:16