从字符串中删除单词列表

时间:2021-04-07 19:19:15

标签: c# linq

我有一个要从字符串中删除的单词列表,我使用以下方法

string stringToClean = "The.Flash.2014.S07E06.720p.WEB-DL.HEVC.x265.RMTeam";

string[] BAD_WORDS = {
            "720p", "web-dl", "hevc", "x265", "Rmteam", "."
        };
    
var cleaned = string.Join(" ", stringToClean.Split(' ').Where(w => !BAD_WORDS.Contains(w, StringComparer.OrdinalIgnoreCase)));

但它不起作用并且输出以下文本

<块引用>

The.Flash.2014.S07E06.720p.WEB-DL.HEVC.x265.RMTeam

2 个答案:

答案 0 :(得分:1)

为此,创建一个可重用的方法将字符串拆分为单词是个好主意。我将把它作为字符串的扩展方法来做。如果您不熟悉扩展方法,请阅读 extension methods demystified

public static IEnumerable<string> ToWords(this string text)
{
    // TODO implement
}

用法如下:

string text = "This is some wild text!"
List<string> words = text.ToWords().ToList();
var first3Words = text.ToWords().Take(3);
var lastWord = text.ToWords().LastOrDefault();

一旦掌握了这种方法,您的问题就很容易解决:

IEnumerable<string> badWords = ...
string inputText = ...
IEnumerable<string> validWords = inputText.ToWords().Except(badWords);

或者您可能想使用 Except(badWords, StringComparer.OrdinalIgnoreCase);

ToWords 的实现取决于您对单词的称呼:所有由点分隔的内容?或者你想支持空格?或者甚至换行?

您的问题的实现:单词是由点分隔的任何字符序列。

public static IEnumerable<string> ToWords(this string text)
{
    // find the next dot:
    const char dot = '.';
    int startIndex = 0;
    int dotIndex = text.IndexOf(dot, startIndex);
    while (dotIndex != -1)
    {
        // found a Dot, return the substring until the dot:
        int wordLength = dotIndex - startIndex;
        yield return text.Substring(startIndex, wordLength;

        // find the next dot      
        startIndex = dotIndex + 1;
        dotIndex = text.IndexOf(dot, startIndex);
    }

    // read until the end of the text. Return everything after the last dot:
    yield return text.SubString(startIndex, text.Length);
}

待办事项:

  • 如果文本以点“.ABC.DEF”开头,请确定要返回的内容。
  • 如果文本以点结尾,请确定要返回的内容:“ABC.DEF。”
  • 如果文本为空,请检查返回值是否是您想要的。

答案 1 :(得分:0)

您的拆分/加入与您的输入不匹配。

也就是说,这是一个快速的单行:

D:/foo/include

这基本上是一个“减少”。性能不是很好,但在已知相当小的字符串上我认为它是可以接受的。如果您必须使用非常大的字符串或非常多的“单词”,您可能会考虑另一种选择,但它应该适用于您提供给我们的示例案例。

编辑:这种方法的缺点是你会得到部分。因此,例如在您的令牌数组中,您有“720p”,但我在这里建议的代码仍将匹配“720px”,但仍有办法解决。例如,代替使用 string clean = BAD_WORDS.Aggregate(stringToClean, (acc, word) => acc.Replace(word, string.Empty)); string 实现,您可以使用匹配您的分隔符的正则表达式,例如 Replace(正则表达式未确认但应该关闭,我添加了一个捕获分隔符以便将其放回下一次传递)