7

我正在尝试通过“过滤器”列表过滤字符串集合......坏词列表。该字符串包含列表中我不想要的单词。

我到目前为止,这里的坏词是“frakk”:

string[] filter = { "bad", "words", "frakk" };

string[] foo = 
{ 
    "this is a lol string that is allowed", 
    "this is another lol frakk string that is not allowed!"
};

var items = from item in foo 
            where (item.IndexOf( (from f in filter select f).ToString() ) == 0)
            select item;

但这不起作用,为什么?

4

3 回答 3

9

您可以使用Any+ Contains

var items = foo.Where(s => !filter.Any(w => s.Contains(w)));

如果您想不区分大小写地比较:

var items = foo.Where(s => !filter.Any(w => s.IndexOf(w, StringComparison.OrdinalIgnoreCase) >= 0));

更新:如果您想排除过滤器列表中至少有一个单词的句子,您可以使用String.Split()and Enumerable.Intersect

var items = foo.Where(sentence => !sentence.Split().Intersect(filter).Any());

Enumerable.Intersect非常有效,因为它Set在引擎盖下使用。将长序列放在首位更有效。由于 Linq 的延迟执行在第一个匹配词处停止。

(请注意,“空”Split包括其他空白字符,如制表符或换行符)

于 2013-07-26T20:53:39.547 回答
2

您需要解决的第一个问题是将句子分解为一系列单词。最简单的方法是基于空格

string[] words = sentence.Split(new char[] {' '}, StringSplitOptions.RemoveEmptyEntries);

从那里你可以使用一个简单的 LINQ 表达式来查找亵渎

var badWords = words.Where(x => filter.Contains(x));

然而,这有点原始的解决方案。它不会处理您可能需要考虑的许多复杂案例

  • 有许多字符可以作为空格。我的解决方案只使用' '
  • 拆分不处理标点符号。所以dog!不会被视为dog. 分解合法字符上的单词可能要好得多
于 2013-07-26T20:56:56.773 回答
0

您最初的尝试没有奏效的原因是这一行:

(from f in filter select f).ToString()

计算结果为 linq 表达式部分隐含的数组迭代器类型名称的字符串。因此,您实际上是在比较以下字符串的字符:

System.Linq.Enumerable+WhereSelectArrayIterator``2[System.String,System.String]

在检查您的短语时,而不是过滤器的单词。

于 2013-07-26T21:14:47.133 回答