【问题标题】:Way to check repeated messages within a string?检查字符串中重复消息的方法?
【发布时间】:2011-11-22 10:57:31
【问题描述】:

消息是准确的,不需要担心中间的变化或符号,现在我只是在寻找一种可以检查如下消息的有效方法。

我有这样一条消息:

string msg = "This is a small message !";

我想检查该消息是否在同一个字符串中重复发送,如下所示:

string msg = "This is a small message !This is a small message !";

或:

string msg = "This is a small message !This is a small message !This is a small message !";

或:

string msg = "This is a small message !This is a small message !This is a small message !This is a small message !This is a small message !";

我有一个 LinkedList<string> 存储收到的最后 3 条消息以及最后 3 条消息,我想匹配当前消息以查看它是否等于当前存储消息之一或重复任何.

foreach (string item in myListOfMessages)
{
    if (string.Equals(msg, item))
    {
        // the message matchs one of the stored messages
    }
    else if (msg.Lenght == (item.Lenght * 2) && string.Equals(msg, string.Concat(item, "", item)))
    {
        // the message is a repetition, and ofc only works when some one sends the message twice in the same string
    }
}

就像我在示例中展示的那样,重复可能非常大,而且我不确定我上面介绍的方法是否最适合我需要的方法。这是我想到的第一个想法,但不久之后我意识到这样会产生更多的工作。

【问题讨论】:

  • 你是在问上面的方法是不是“最好”的方法?
  • @Polity 不,我不是在问这是否是最好的方法,因为我已经在问题中回答了自己。 Way to check repeated messages within a string? 这就是问题所在。

标签: c# .net-4.0 string-matching


【解决方案1】:

Linq 救援:

string msg = "This is a small message !";
string otherMsg = "This is a small message !This is a small message !This is a small message !This is a small message !This is a small message !";

bool isRepeated = Enumerable.Range(0, otherMsg.Length / msg.Length)
                            .Select(i => otherMsg.Substring(i *  msg.Length,  msg.Length))
                            .All( x => x == msg);

这种方法基本上取第一条消息长度的子字符串,并将每个块与原始消息进行比较。

包装在一个带有一些预检查的方法中:

public bool IsRepeated(string msg, string otherMsg)
{
    if (otherMsg.Length < msg.Length || otherMsg.Length % msg.Length != 0)
        return false;

    bool isRepeated = Enumerable.Range(0, otherMsg.Length / msg.Length)
                                .Select(i => otherMsg.Substring(i * msg.Length, msg.Length))
                                .All(x => x == msg);
    return isRepeated;
}

编辑:

上述方法会生成不必要的字符串,这些字符串必须被 gc'ed - 一个更有效和更快的解决方案:

public bool IsRepeated(string msg, string otherMsg)
{
    if (otherMsg.Length < msg.Length || otherMsg.Length % msg.Length != 0)
        return false;

    for (int i = 0; i < otherMsg.Length; i++)
    {
        if (otherMsg[i] != msg[i % msg.Length])
            return false;
    }
    return true;
}

【讨论】:

  • 效果很好 我正在考虑使用 % 但不确定它是否会奏效。
【解决方案2】:

您可以尝试使用正则表达式

string msg = "This is a small message !";
string Input = "This is a small message !This is a small message !";

System.Text.RegularExpressions.Regex r = new System.Text.RegularExpressions.Regex(msg);
System.Text.RegularExpressions.MatchCollection Matches = r.Matches(Input);

int Count = Matches.Count; //Count = 2

【讨论】:

  • 请注意,这将计算msgInput 中的所有出现,即使两者之间有新的东西。如果我正确理解您的问题,这不是您想要的。
  • 好点。这不是我想要的,因为我需要完全匹配
  • @nw 好点,没考虑到这一点!
【解决方案3】:
private int countRepeats(string msg, string item)
{
   if(string.Replace(msg, item).Length > 0)
      return 0;

   return msg.Length / item.Length;
}

【讨论】:

    【解决方案4】:
    static void Main(string[] args)
            {
                string msg = "This is a small message !This is a small message !This is a small message !";
                string substring = "This is a small message !";
    
                string[] split = msg.Split(new string[] { substring }, StringSplitOptions.None);
    
                Console.WriteLine(split.Length - 1);
    
                foreach (string splitPart in split)
                {
                    if (!String.IsNullOrEmpty(splitPart))
                        Console.WriteLine("Extra info");
                }
            }
    

    【讨论】:

    • 这不会像正则表达式那样失败吗?
    • 啊,真的。没有看到那个答案和它的 cmets。
    • 好吧,如果原始消息不包含任何额外内容,则拆分数组仅包含空字符串。如果拆分数组的任何元素不为空,则说明原始消息中有一些无关字符
    • @xbonez: +1 我真的很喜欢这个想法 - 你可以通过使用 StringSplitOptions.RemoveEmptyEntries: bool isRepeated = otherMsg.Split(new string[] { msg }, StringSplitOptions.RemoveEmptyEntries).Length == 0; 让它变得更好
    猜你喜欢
    • 1970-01-01
    • 2017-04-12
    • 2015-01-22
    • 1970-01-01
    • 2016-02-12
    • 2014-10-19
    • 2021-03-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多