【问题标题】:Regex Specific Search lines in any order and may or may not exist任何顺序的正则表达式特定搜索行,可能存在也可能不存在
【发布时间】:2015-03-15 16:29:49
【问题描述】:

直截了当。我正在开发一个 IRC 机器人,而且我正站在一堵砖墙上,从今天早上 4 点开始我就一直在敲打我的头。

我正在尝试专门在正则表达式组中对 IRC Raw 005 (IS_SUPPORTED) 字符串进行排序。示例字符串如下所示。

Nickname MAXTARGETS=20 WALLCHOPS WATCH=128 WATCHOPTS=A SILENCE=15 MODES=12 CHANTYPES=# PREFIX=(qaohv)~&@%+ CHANMODES=beI,kfL,lj,psmntirRcOAQKVCuzNSMTGZ NETWORK=Network CASEMAPPING=ascii EXTBAN=~,qjncrRa ELIST=MNUCT

到目前为止,我已经清理了数据包的其余部分,所以这一行正是我正在使用的,尽管它可能有我的示例中未显示的其他字段。我有所有字符串都以该数据包中每个可能的字段命名。我希望将每个字符串、整数和布尔值设置为每个结果信息,按 C# 中的正则表达式组排序

为了更清楚,

  • 我的public int maxtargets 将设置为正则表达式组的结果 <maxtargets>
  • 我的public bool wallchops 将设置为真,如果 正则表达式组<wallchops> 返回自身。
  • 我的public string chantypes 将设置为正则表达式组<chantypes> 的结果

在字段可能不存在且字段顺序可能完全不同的情况下,我无法组装搜索和匹配字段和值的正则表达式搜索字符串。

我希望我对此很清楚,并会填补我忘记的任何空白。

【问题讨论】:

    标签: c# regex string irc


    【解决方案1】:

    在一个字段可能不存在的情况下,字段的顺序可能完全不同。

    我认为为上述案例编写正则表达式并不是最佳实践。相反,您可以使用简单的字符串方法来实现您的目标。

    class IrcParser
    {
        private string input;
    
        public IrcParser(string input)
        {
            this.input = input;
        }
    
        public Irc GetResult()
        {
            Irc irc = new Irc();
            string[] result = input.Split();
            for (int i = 0; i < result.Length; i++)
            {
                string[] FieldValue = result[i].Split('=');
                switch (FieldValue[0])
                 {
                    case "MAXTARGETS":
                         irc.maxTargets = Convert.ToInt32(FieldValue[1]);
                         break;
                    case "WALLCHOPS":
                         irc.wallChops = true;
                         break;
                    case "CHANTYPES":
                        irc.chanTypes = FieldValue[1];
                        break;
                }
            }
            return irc;
        } 
    
        public Irc GetResultByRegex()
        {
            Irc irc = new Irc();
            MatchMaxTargets(ref irc.maxTargets);
            MatchWallChops(ref irc.wallChops);
            MatchChanTypes(ref irc.chanTypes);
            return irc;
        }
    
        private void MatchMaxTargets(ref int maxTargets)
        {
            Regex regex = new Regex(@"(?<=MAXTARGETS=)(\d+)");
            Match m = regex.Match(input);
            if (m.Success){
                maxTargets = Convert.ToInt32(m.Groups[1].Value);
            }
        }
    
        private void MatchWallChops(ref bool wallChops)
        {
            if (Regex.IsMatch(input, "WALLCHOPS"))
            {
                wallChops = true;
            }
        }
    
        private void MatchChanTypes(ref string chanTypes)
        {
            Regex regex = new Regex(@"(?<=CHANTYPES=)(.*?)(?=\s)");
            Match m = regex.Match(input);
            if (m.Success)
            {
                chanTypes = m.Groups[1].Value;
            }
        }
    
    }
    
    class Irc
    {
        public int maxTargets;
        public bool wallChops;
        public string chanTypes;
    }
    

    更新: 我添加了对单个字段值执行 REGEX 匹配的方法。如果我们编写单行 REGEX,组结果顺序将根据字段可用性而改变。(在这种情况下,您无法将组值分配给适当的字段。)

    希望对您有所帮助。
    --SJ

    【讨论】:

    • 虽然我同意可能有更好的方法可以做到这一点,但是我正在寻找一个正则表达式字符串来返回它。我正在尝试学习正则表达式,以及为什么这会或不会成为我想要完成的最佳实践。我想在代码中犯自己的错误并从中学习并最终改善结果。我一定会采用你的字符串方法,看看我能在这方面做些什么。但是,我最终需要一个正则表达式来解决我的问题。
    • 我们无法为您的案例编写单行正则表达式模式。因为,您的字段值可能会也可能不会出现在给定的字符串中。我更新了我的答案。
    【解决方案2】:

    一位朋友终于帮我解决了这个问题,我们想出了如何成功匹配我上面的字符串,不管它有没有字段,不管它可能是什么顺序。

    (?:(?:SILENCE=(?<silence>\d+)\s?)|(?:MODES=(?<modes>\d+)\s?)|(?:CHANTYPES=(?<chantypes>\S+)\s?)|(?:PREFIX=(?<prefix>\S+)\s?)|(?:MAXTARGETS=(?<maxtargets>\d+)\s?)|(?:WATCH=(?<watch>\d+)\s?)|(?<wallchops>WALLCHOPS)|(?:NETWORK=(?<network>\w+)\s?)|(?:CASEMAPPING=(?<casemapping>\w+)\s?)|(?:CHANMODES=(?<chanmodes>\S+)\s?)|(?:EXTBAN=(?<extban>\S+)\s?)|(?:ELIST=(?<elist>\w+)\s?)|(?:WATCHOPTS=(?<watchopts>\S+)\s?)\s?)
    

    是的,我意识到这是一个巨大的正则表达式搜索字符串,它会根据我的需要将行作为组返回。我也意识到这在实践中并不是最好的主意。这条搜索线会增长到巨大的规模并且可以,并且可能会产生大量的开销并浪费 CPU 时间来执行。

    SJ, 非常感谢您的反馈,我将使用您建议的代码并以这种方式使其工作,当然还有一些小的改动。

    【讨论】:

      猜你喜欢
      • 2017-08-04
      • 2015-07-07
      • 1970-01-01
      • 1970-01-01
      • 2012-12-31
      • 2016-03-07
      • 2018-01-21
      • 2023-03-06
      • 2014-07-15
      相关资源
      最近更新 更多