如何从C#中的句子算起

时间:2016-12-27 00:48:02

标签: c#

所以,我正在为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)

2 个答案:

答案 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是单词数。

LINQ版本

    public bool CheckSentenceLinq(string rawMessage)
    {
        var lower = rawMessage.ToLower();

        return _filteredWords
                   .Where(x => x.IsSentence)
                   .Count(x => lower.Contains(x.Word)) >= 5;
    }

编辑2:根据@S.C.评论

更新了LINQ

@S.C.

  

对于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();
    }

ToUpper vs ToLower

正如@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)

我相信有人已经发布了正确答案,我只是在这里提供替代方案。

因此,我会提供正则表达式解决方案,而不是forloopforeach

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;