C# 如何从C语言中的一个句子数数#

C# 如何从C语言中的一个句子数数#,c#,C#,因此,我正在为C#中的游戏服务器创建一个单词过滤器,基本上我正在尝试搜索句子中的禁用单词,并用干净的单词替换它们。我已经这样做了,但是现在我要扫描句子,查找句子中禁止使用的单词列表。我在这一点上没有希望了,而且我似乎无法控制自己的情绪 基本上,我是ChatManager中的check句子(Message),需要以下代码来计数并返回continue如果值大于5。到目前为止,我已经: public bool CheckSentence(string Message) { fo

因此,我正在为C#中的游戏服务器创建一个单词过滤器,基本上我正在尝试搜索句子中的禁用单词,并用干净的单词替换它们。我已经这样做了,但是现在我要扫描句子,查找句子中禁止使用的单词列表。我在这一点上没有希望了,而且我似乎无法控制自己的情绪

基本上,我是ChatManager中的
check句子(Message)
,需要以下代码来计数并返回
continue如果值大于5。到目前为止,我已经:

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个
消息包含(Filter.Word)

如果这变得太慢,您最好在哈希集中缓存过滤后的单词列表,并迭代消息中的每个单词,检查它是否存在于哈希集中,这将给您O(n)的速度,其中n是单词数

LINQ版本 编辑2:根据注释更新LINQ 借


对于linq版本,不需要计算超过前五个。返回_filteredWords.Where(x=>x.IsSentence&&lower.Contains(x.Word)).Skip(5.Any()

图珀对托洛尔 正如@devestation所提到的,根据Microsoft,最好使用
ToUpperInvariant()
进行字符串比较,而不是
ToLowerInvariant()

编辑:使用“继续”
我相信有人已经给出了正确的答案,我只是想提供一个替代方案

因此,我将为您提供正则表达式解决方案,而不是执行
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声明

using System.Linq;
using System.Text.RegularExpressions;

请问@MitchWheath您是否尝试过将邮件拆分为单个单词,并计算与您的筛选器匹配的单词数?我不知道该如何做,这就是我请求社区帮助的原因。我自学成才,我还在学习如何做事。这是一件我已经坚持了一段时间的大事@casablanca@Liam:亵渎过滤器不起作用:请参见斯肯索普的“到目前为止,它工作得很好”-这样你就没有问题了?如果你制作过滤器,效果会更好。请将单词改为小写。另外,ToUpper更快:)@devestasion我假设他的过滤词已经存储在较低的…将返回计数>=5;就好像我要继续一样;?否,因为
返回计数>=5
,不在
foreach
块内,因此没有可继续的内容<当您想在
foreach
循环中跳到下一个迭代时,使用code>continue
。在这里,在循环中计算单词的数量。对于linq版本,不需要超过前五个<代码>返回_filteredWords.Where(x=>x.IsSentence&&lower.Contains(x.Word)).Skip(5.Any()您提到regex阻止循环,但Join(至少在t-SQL世界中)的速度不如您连接两个集合之间所有可能的组合的速度慢,因此“No”更快?@Edward yes,string.Join用于下面的循环。但我是关于他的方法的循环。关于更快,我们不知道,除非我们中的一个人测试它。
    public bool CheckSentenceLinq(string rawMessage)
    {
        var lower = rawMessage.ToLower();

        return _filteredWords
                   .Where(x => x.IsSentence)
                   .Where(x => lower.Contains(x.Word))
                   .Skip(5)
                   .Any();
    }
    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;
    }
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;
}
using System.Linq;
using System.Text.RegularExpressions;