所以,我正在为C#中的游戏服务器创建一个单词过滤器,基本上我试图用句子来处理被禁词并用干净的单词替换它们。我已经这样做了,但是现在我想要扫描一下句子禁止的单词列表。我在这方面毫无希望,我似乎无法绕过它。
基本上我在ChatManager中是CheckSentence(Message)
,如果值超过5,需要以下代码来计算并返回continue;
。到目前为止,我有:
public bool CheckSentence(string Message)
{
foreach (WordFilter Filter in this._filteredWords.ToList())
{
if (Message.ToLower().Contains(Filter.Word) && Filter.IsSentence)
{
// count Message, if message contains >5
// from (Message.Contains(Filter.Word))
// continue; else (ignore)
}
}
return false;
}
我不太确定这是否有意义,但我希望它继续下去;如果有超过5 Message.Contains(Filter.Word)
答案 0 :(得分:2)
public bool CheckSentence(string rawMessage)
{
var lower = rawMessage.ToLower();
var count = 0;
foreach (WordFilter Filter in this._filteredWords.ToList())
{
if (lower.Contains(Filter.Word) && Filter.IsSentence)
{
count++;
}
}
return count >= 5;
}
如果这变得太慢,你可能更好地缓存HashSet中的过滤单词列表,并迭代消息中的每个单词,检查它是否存在于HashSet中,这将给你O(n)速度,其中N是单词数。
public bool CheckSentenceLinq(string rawMessage)
{
var lower = rawMessage.ToLower();
return _filteredWords
.Where(x => x.IsSentence)
.Count(x => lower.Contains(x.Word)) >= 5;
}
对于linq版本,没有必要计算前五个。 return _filteredWords.Where(x => x.IsSentence&& lower.Contains(x.Word))。Skip(5).Any();
public bool CheckSentenceLinq(string rawMessage)
{
var lower = rawMessage.ToLower();
return _filteredWords
.Where(x => x.IsSentence)
.Where(x => lower.Contains(x.Word))
.Skip(5)
.Any();
}
正如@DevEstacion所提到的那样,根据Microsoft best practices for using string recommendations here,最好使用ToUpperInvariant()
进行字符串比较,而不是ToLowerInvariant()
。
public bool CheckSentenceWithContinue(string rawMessage)
{
var lower = rawMessage.ToLower();
var count = 0;
foreach (WordFilter Filter in this._filteredWords.ToList())
{
if (!Filter.IsSentence)
continue; // Move on to the next filter, as this is not a senetece word filter
if (!lower.Contains(Filter.Word))
continue; // Move on to the next filter, as the message does not contain this word
// If you are here it means filter is a Sentence filter, and the message contains the word, so increment the counter
count++;
}
return count >= 5;
}
答案 1 :(得分:0)
我相信有人已经发布了正确答案,我只是在这里提供替代方案。
因此,我会提供正则表达式解决方案,而不是forloop
或foreach
。
public bool CheckSentence(string rawMessage)
{
/*
The string.Join("|", _filteredWords) will create the pattern for the Regex
the '|' means or so from the list of filtered words, it will look it up on
the raw message and get all matches
*/
return new Regex(string.Join("|", _filteredWords.Where(x => x.IsSentence)),
RegexOptions.IgnoreCase | RegexOptions.Compiled).Match(rawMessage).Length >= 5;
}
好处?更短,防止循环,可以更快:)
不要忘记在.cs文件
之上添加这两行使用声明using System.Linq;
using System.Text.RegularExpressions;