Заменить несколько строковых элементов в C # - PullRequest
69 голосов
/ 24 августа 2009

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

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

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

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

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

Ответы [ 8 ]

98 голосов
/ 24 августа 2009

Быстрее - нет. Более эффективно - да, если вы будете использовать класс 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();
    }
}
13 голосов
/ 24 августа 2009

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

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

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

11 голосов
/ 24 августа 2009

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

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();
    }
}
10 голосов
/ 06 мая 2014

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

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));
4 голосов
/ 21 мая 2014

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

2 голосов
/ 09 ноября 2017

Другой вариант использования 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);
}
2 голосов
/ 17 сентября 2011

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

Редактировать: Вы можете использовать Dictionary<Key,List<Values>>, чтобы получить тот же результат, что и строка [] []

0 голосов
/ 16 марта 2017
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]);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...