繁体   English   中英

从字符串中删除单词列表

[英]Remove list of words from string

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

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

但它不起作用下面的文字是 output

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

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

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”。
  • 如果文本为空,请检查返回值是否是您想要的。

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

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

string clean = BAD_WORDS.Aggregate(stringToClean, (acc, word) => acc.Replace(word, string.Empty));

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

编辑:这种方法的缺点是你会得到部分。 因此,例如在您的令牌数组中,您有“720p”,但我在此处建议的代码仍将匹配“720px”,但仍有解决方法。 例如,代替使用stringReplace实现,您可以使用匹配分隔符的正则表达式,例如Regex.Replace(acc, $"[. ]{word}([. ])", "$1") (regex未确认但应该关闭,我为分隔符添加了一个捕获,以便将其放回以进行下一次传递)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM