Заменить несколько строковых элементов в C #

Есть ли лучший способ сделать это ... Я

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

Мы расширили класс string, чтобы сохранить его до одной работы, но есть ли более быстрый способ?

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

Просто для удовольствия (и чтобы прекратить аргументы в комментариях) яМы продемонстрировали различные примеры, приведенные ниже.

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

Опция регулярных выражений получает ужасные результаты; опция словаря подходит быстрее всего; длинная версия замены строителя строк немного быстрее, чем короткая рука.

 Chris McKee15 сент. 2014 г., 02:24
@toad Привет с 2009 года; В апреле я добавил комментарий об этой вопиющей ошибке. Суть обновлена, хотя я пропустил D. Версия словаря все еще быстрее.
 toad12 сент. 2014 г., 23:23
Исходя из того, что у вас есть в ваших тестах, похоже, что словарная версия нея делаю все замены, которые, как я подозреваю, делают это быстрее, чем решения StringBuilder.
 Tot Zam17 мар. 2016 г., 21:19
 Chris McKee22 июн. 2016 г., 15:27
@TotZam, по крайней мере, проверьте даты, прежде чем пометить вещи; это с 2009 года то с 2012 года

Ответы на вопрос(8)

Может быть, немного более читабельным?

    public static class StringExtension {

        private static Dictionary _replacements = new Dictionary();

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

Также добавьте New In Town 'Предложение о StringBuilder ...

 Chris McKee06 июл. 2013 г., 00:22
или конечно ... частный статический словарь только для чтения <строка, строка> Замены = новый словарь <строка, строка>() {{"&", "а также" }, {",", "" }, {" "," " } /* так далее */ }; public static string Clean (эта строка s) {return Replacements.Keys.Aggregate (s, (current, toReplace) => current.Replace (toReplace, Replacements [toReplace])); }
 ANeves04 авг. 2011 г., 12:04
Это было бы более читабельным, как это:private static Dictionary _replacements = new Dictionary() { {"&", "and"}, {",", ""}, {" ", " "} /* etc */ };

В предложенных решениях можно оптимизировать одну вещь. Имея много звонковReplace() заставляет код делать несколько проходов по одной и той же строке. С очень длинными строками решения могут быть медленными из-за нехватки кеша процессора. Может быть, стоит подуматьзамена нескольких строк за один проход.

Если вы просто ищете красивое решение и неНе нужно экономить несколько наносекунд, как насчет сахара LINQ?

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

var output = replacements.Aggregate(input, (current, replacement) => current.Replace(replacement.Key, replacement.Value));
 Chris McKee15 сент. 2014 г., 02:26
Аналогично примеру C в Gist (если посмотреть выше, в комментарии есть более уродливый оператор linq)
 TimS15 сент. 2014 г., 02:36
Интересно, что вы определяете функциональный статус какуродливее» чем процедурный.
 Chris McKee15 сент. 2014 г., 10:48
не собираюсь спорить об этом; это просто предпочтение. Как вы говорите, linq - это просто синтаксический сахар; и как я уже сказал,Я уже поставил эквивалент выше кода :)
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]);
}
 Neil16 мар. 2017 г., 01:31
Вы должны рассмотреть возможность добавления контекста к вашим ответам. Как краткое объяснение того, чтоИ делает ли это, и если уместно, почему вы написали это так, как написали.

это будет более эффективным:

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();
    }
}
 Chris McKee06 июл. 2013 г., 00:16
Это на самом деле медленнее. BenchmarkOverhead ... 13ms StringClean-user151323 ... 2843ms StringClean-TheVillageIdiot ... 2921ms Зависит от повторов, но ответ выигрываетgist.github.com/anonymous/5937596
 Piotr Kula12 февр. 2013 г., 11:55
Действительно трудно читать. Я уверен, что вы знаете, что он делает, но младший разработчик поцарапает свою голову от того, что на самом деле происходит. Я согласен - я также всегда ищу короткую руку, чтобы написать что-то - но это было только для моего собственного удовлетворения. Другие люди сходили с ума от кучи беспорядка.

Другой вариант использования linq

[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);
}
 Tok'17 нояб. 2017 г., 23:17
Вы можете объявитьvar removeList = new List { /*...*/ }; тогда просто позвониremoveList.ForEach( /*...*/ ); и упростить ваш код. Обратите внимание, что это неТ полностью ответить на вопрос, потому чтовсе найденные строки заменяются на.String.Empty
Решение Вопроса

Быстрее - нет. Более эффективно - да, если вы будете использоватьStringBuilder учебный класс. В вашей реализации каждая операция генерирует копию строки, которая при определенных обстоятельствах может ухудшить производительность. Строкинеизменный объекты, поэтому каждая операция просто возвращает измененную копию.

Если вы ожидаете, что этот метод будет активно вызываться на несколькихStrings значительной длины, может быть, лучшемигрировать» его реализация наStringBuilder учебный класс. При этом любая модификация выполняется непосредственно в этом экземпляре, поэтому вы избавляете от ненужных операций копирования.

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();
    }
}
 Chris McKee25 апр. 2014 г., 11:30
Это хороший момент; в его нынешнем виде он использовался для очистки URL, поэтому тестирование на 100 КБ - 1 МБ было бы нереальным. Я обновлю бенчмарк, чтобы он использовал все это, хотя это было ошибкой.
 Chris McKee06 июл. 2013 г., 22:28
Для наглядности словарный ответ самый быстрыйstackoverflow.com/a/1321366/52912
 Leif14 февр. 2014 г., 09:42
В вашем тесте наgist.github.com/ChrisMcKee/5937656 тест словаря не завершен: он не делает все замены и " " заменяет "не  ", Не все замены могут быть причиной, почемуСамый быстрый в тесте. Замена регулярного выражения также не завершена. Но самое главное, ваша строка TestDataочень короткая. Подобно принятым состояниям ответа, строка должна иметь значительную длину, чтобы StringBuilder имел преимущество. Не могли бы вы повторить тест со строками 10 КБ, 100 КБ и 1 МБ?

я делаю что-то подобное, но в моем случае яЯ делаю сериализацию / десериализацию, поэтому мне нужно иметь возможность идти в обоих направлениях. Я обнаружил, что использование строки [] [] работает почти идентично словарю, включая инициализацию, но вы можете пойти и в другом направлении, возвращая заменители к их исходным значениям, что словарь на самом деле не представляет.настроен делать.

Изменить: вы можете использоватьDictionary чтобы получить тот же результат, что и строка [] []

Ваш ответ на вопрос