【问题标题】:Replace multiple words in a string from a list of words从单词列表中替换字符串中的多个单词
【发布时间】:2019-11-13 23:44:51
【问题描述】:

我有一个单词列表:

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”不应该被删除,因为它与 BAD WORDS 不完全匹配。

谁能给我建议?

【问题讨论】:

  • 看起来像是正则表达式的工作。
  • 你为什么要加入这行string w = string.Format(" {0} ", word);
  • 您的任务是什么,您的代码看起来不错?只需删除 if 并做一个开始和结束。
  • @Nikhil Agrawal:前后放置空格。例如,如果你只保留这个词,它也会匹配 oxxx。
  • 您的if 是不必要的。最好从while 开始,以避免第一次检查两次。

标签: c# string replace


【解决方案1】:
string cleaned = Regex.Replace(input, "\\b" + string.Join("\\b|\\b",BAD_WORDS) + "\\b", "")

【讨论】:

  • 等一下,我错过了一些东西......工作......在那里,修复。 :)
  • 嘿... :) 谢谢痴呆症。照我说的做,而不是照我做的。我只是想说所有的嵌套和 LINQing 和循环都有一个简单的旧/久经考验的方法。
  • +1 用于在开始或其他边界条件下捕获单词。作为奖励,如果需要多次替换,生成的正则表达式可以被缓存以供重复使用。我会使用 Regex.Escape 虽然以防万一 BAD_WORDS 包含对正则表达式语法重要的内容。
  • 可能不像其他人指出的那样完美的代码改进,但 +1 用于使用正则表达式单词边界而不是拆分。
【解决方案2】:

这对于 Linq 和 Split 方法来说都是一项伟大的任务。试试这个:

return string.Join(" ", input.Split(' ').Where(w => !BAD_WORDS.Contains(w)));

【讨论】:

  • 只要空间足够。这不会捕获开头或结尾的单词,如果后面跟着换行符,如果后面跟着标点符号等。如果需要处理这种情况,基于正则表达式的答案会做得更好。
  • 这是在单词之间添加额外的空格,我不知道为什么
  • 空字符串与其他项目两侧的空格相连。我已经编辑了答案(现在更整洁了!)
【解决方案3】:

您可以使用 StartWith 和 EndsWith 方法,例如:

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

希望这能解决您的问题。

【讨论】:

  • 你的意思是 OR 不是 AND?在您的测试中,它必须同时开始、结束和包含单词。
  • 这仍然会捕获部分单词(badword = 'aoooo',actual word='aoooome',它会删除'aoooo'。
【解决方案4】:

在字符串变量input 之前和之后放置假空格。这样它就会检测到第一个词和最后一个词。

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();

【讨论】:

  • 这是一个好主意,可以修复我的代码,但是没有更好的解决方案吗?代码对我来说似乎有点奇怪,我写它是因为我没有其他想法。
【解决方案5】:

您可以将文本中的单词存储到一个列表中。然后检查所有单词是否在错误列表中,如下所示:

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

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

【讨论】:

    【解决方案6】:

    只是想指出,你应该这样做:

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

    不需要那个 if 和 'w' 变量,无论如何我都会使用上面的答案,Antonio Bakula,首先想到的是这个。

    【讨论】:

    • 您正在尝试替换您已从代码中删除的w。如果没有w,它也会替换部分单词匹配。
    【解决方案7】:

    根据以下帖子,最快的方法是使用 Regex 和 MatchEvaluator : Replacing multiple characters in a string, the fastest way?

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-12-03
      • 2022-01-17
      • 1970-01-01
      • 2021-06-12
      • 2018-08-05
      • 2013-03-17
      • 2012-11-26
      相关资源
      最近更新 更多