Вопрос по replace, string, c# – Заменить несколько слов в строке из списка слов

2

у меня есть список слов:

string[] BAD_WORDS = { "xxx", "o2o" } // My list is actually a lot bigger about 100 words

и у меня есть некоторый текст (обычно короткий, максимум 250 слов), который мне нужно удалить всеBAD_WORDS в этом.

я пробовал это:

    foreach (var word in BAD_WORDS)
    {
        string w = string.Format(" {0} ", word);
        if (input.Contains(w))
        {
            while (input.Contains(w))
            {
                input = input.Replace(w, " ");
            }
        }
    }

но если текст начинается или заканчивается плохим словом, он не будет удален. я сделал это с пробелами, поэтому он не будет совпадать с частичными словами, например, "oxxx" не должны быть удалены, так как это не точное совпадение с плохими словами.

Кто-нибудь может дать мне совет по этому поводу?

Похоже, работа для регулярных выражений. Oded
Почему вы включили эту строкуstring w = string.Format(" {0} ", word);? Nikhil Agrawal
@Nikhil Agrawal: чтобы поставить пробелы до и после. Если вы оставите только слово, оно также будет соответствовать oxxx, например. Tudor
какой у вас квест, ваш код выглядит нормально? Просто удалите if и сделайте старт с и закончите. Peter
Вашif не нужно Лучше начать сwhile чтобы избежать проверки дважды в первый раз. Tim S.

Ваш Ответ

7   ответов
0

Просто хотел бы отметить, что вы должны были сделать только с помощью whiole внутри вашего, вот так:

   foreach (var word in BAD_WORDS)
{
    while (input.Contains(String.Format(" {0} ", word);))
    {
        input = input.Replace(w, " ");
    }
}

Нет необходимости в этом, если и 'w' Переменная, в любом случае я использовал ответ выше меня, что Антонио Бакула, сначала подумайте, вот что.

Вы пытаетесь заменитьw который вы удалили из кода. безw, он также заменит частичные совпадения слов. Dementic
1

Поместите поддельные пробелы до и после строки varaibleinput, Таким образом, он обнаружит первые и последние слова.

input = " " + input + " ";

 foreach (var word in BAD_WORDS)
    {
        string w = string.Format(" {0} ", word);
        if (input.Contains(w))
        {
            while (input.Contains(w))
            {
                input = input.Replace(w, " ");
            ,}
        }
    }

Затем обрежьте строку:

input = input.Trim();
Это хорошая идея, которая исправит мой код, но разве нет лучшего решения для этого? код кажется мне немного странным, я написал его, потому что у меня не было другой идеи. Dementic
1

Вы можете хранить слова из текста в один список. Затем просто проверьте все слова, если они находятся в плохом списке, что-то вроде этого:

List<string> myWords = input.Split(' ').ToList();
List<string> badWords = GetBadWords();

myWords.RemoveAll(word => badWords.Contains(word));
string Result = string.Join(" ", myWords);
5

Это отличная задача для Linq, а также метод Split. Попробуй это:

return string.Join(" ",
                   input.Split(' ').Select(w => BAD_WORDS.Contains(w) ? "" : w));
отлично, я люблю linq! Dementic
Пока места достаточно. Это не поймает слова в начале или в конце, если за ними будет следовать новая строка, если после них будет пунктуация и т. Д. Если необходимо разобраться с этим случаем, ответы на основе регулярных выражений сделают лучше
1

Вы можете использовать методы StartWith и EndsWith, такие как:

while (input.Contains(w) || input.StartsWith(w) || input.EndsWith(w) || input.IndexOf(w) > 0)
{
   input = input.Replace(w, " ");
}

Надеюсь, это решит вашу проблему.

это все равно будет отлавливать частичные слова (badword = 'aoooo' '; фактическое слово =' aoooome '', оно удалит 'aoooo' apos ;. Dementic
Используйте || вместо & amp; & amp;
Спасибо @Tudor, я обновил свой ответ.
Вы не имеете в виду ИЛИ не И? С вашим тестом он должен одновременно начинаться, заканчиваться и содержать слово.
0

Согласно следующему посту самый быстрый способ - использовать Regex и MatchEvaluator: Замена нескольких символов в строке, самый быстрый способ?

        Regex reg = new Regex(@"(o2o|xxx)");
        MatchEvaluator eval = match =>
        {
            switch (match.Value)
            {
                case "o2o": return " ";
                case "xxx": return " ";
                default: throw new Exception("Unexpected match!");
            }
        };
        input = reg.Replace(input, eval);
14

string cleaned = Regex.Replace(input, "\\b" + string.Join("\\b|\\b",BAD_WORDS) + "\\b", "")
Подожди, я что-то упустил ... работает ... Там, починить. :)
Возможно, не идеальный код, как другие отметили улучшения, но +1 для использования границ слова регулярного выражения вместо разделения.
Хи ... :) Спасибо, Дементик. Делай, как я говорю, а не как я. Я только пытался сказать, что у всех вложений, LINQing и циклов был простой более старый / проверенный метод.
+1 для ловли слов в начале или других граничных условиях. В качестве бонуса, если замену необходимо выполнить несколько раз, созданное регулярное выражение можно кэшировать для повторного использования. Я используюRegex.Escape хотя на всякий случайBAD_WORDS содержал что-то существенное для синтаксиса регулярных выражений.

Похожие вопросы