我有一个要从字符串中删除的单词列表,我使用以下方法
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
答案 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);
}
待办事项:
答案 1 :(得分:0)
您的拆分/加入与您的输入不匹配。
也就是说,这是一个快速的单行:
D:/foo/include
这基本上是一个“减少”。性能不是很好,但在已知相当小的字符串上我认为它是可以接受的。如果您必须使用非常大的字符串或非常多的“单词”,您可能会考虑另一种选择,但它应该适用于您提供给我们的示例案例。
编辑:这种方法的缺点是你会得到部分。因此,例如在您的令牌数组中,您有“720p”,但我在这里建议的代码仍将匹配“720px”,但仍有办法解决。例如,代替使用 string clean = BAD_WORDS.Aggregate(stringToClean, (acc, word) => acc.Replace(word, string.Empty));
的 string
实现,您可以使用匹配您的分隔符的正则表达式,例如 Replace
(正则表达式未确认但应该关闭,我添加了一个捕获分隔符以便将其放回下一次传递)