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