任何顺序的正则表达式特定搜索行,可能存在也可能不存在

Regex Specific Search lines in any order and may or may not exist

开门见山。我正在开发一个 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#

中的正则表达式组排序

为了更清楚,

我在组装用于搜索和匹配字段和值的正则表达式搜索字符串时遇到问题,在字段可能不存在且字段顺序可能完全不同的情况下。

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

in the situations that a field may not exist, and the fields may be in a completely different order.

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

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

一位朋友终于帮我解决了这个问题,我们想出了如何成功匹配我上面的字符串,无论它是否有一个字段,无论它的顺序如何。

(?:(?: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?)

是的,我意识到这是一个巨大的 Regex 搜索字符串,它会 return 按我的意愿将这些行分组。我也意识到这在实践中并不是最好的主意。此搜索行会增长到巨大的规模,并且可能会产生大量开销并浪费 CPU 执行时间。

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