Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 订购一组正则表达式模式或获得最大正则表达式匹配_C#_Sql_Regex_Sorting - Fatal编程技术网

C# 订购一组正则表达式模式或获得最大正则表达式匹配

C# 订购一组正则表达式模式或获得最大正则表达式匹配,c#,sql,regex,sorting,C#,Sql,Regex,Sorting,给定一个属于正则表达式模式的数字列表,按该数值中的最后4个数字进行排序。 我有一个regex(电话号码)模式的列表,我试图按最后4个字符对它们进行排序。以下是电话号码的示例列表: 8062 \+13066598273 4083100 408320[0-3] 408320[4-6] 752[234569] \+13066598305 8059 我想按最后4个数字对这些数字重新排序,这样我就可以得到如下列表: 4083100 408320[0-3] 408320[4-6] 752[234569]

给定一个属于正则表达式模式的数字列表,按该数值中的最后4个数字进行排序。

我有一个regex(电话号码)模式的列表,我试图按最后4个字符对它们进行排序。以下是电话号码的示例列表:

8062
\+13066598273
4083100
408320[0-3]
408320[4-6]
752[234569]
\+13066598305
8059
我想按最后4个数字对这些数字重新排序,这样我就可以得到如下列表:

4083100
408320[0-3]
408320[4-6]
752[234569]
8059
8062
\+13066598273
\+13066598305
现在,如果我的模式只是数字,我可以在SQL或MVC项目中轻松地对它们进行排序。在SQL中,我可以使用ORDER BY RIGHT(模式,4),或者在C#MVC中,我可以使用patterns=patterns.OrderByDescending(s=>s.Substring(…等…)对我的IQueryable列表进行排序

模式有点难。括号计为字符,因此按最后4个字符排序也不起作用

C#、MVC或SQL中是否有任何内置实用程序允许我将正则表达式模式转换为最大可能的匹配

  • 给定正则表达式模式,返回与我的条件匹配的最大可能匹配正则表达式。例如,如果我有模式4[12]00[1-3],我将有6个可能的结果:41001、41002、41003、42001、42002、42003。然后我可以得到尽可能大的数字,并使用它在我的原始正则表达式列表中进行排序。
    • 正则表达式模式不包含任何像*或+,可能导致无限组合的特殊字符
  • 可能有一个C#库可以完全按照我的要求对正则表达式模式字符串进行排序
编辑:

我已经接受了迭戈的回答,但我花了一点时间才明白这一点。对于其他想知道它在做什么的读者,这就是我认为迭戈正在做的:

  • 设定一个整数范围,从9999开始,一直返回到0。[9999]、[9998]、[9997]…[0]
  • 用单个字符替换字符串的正则表达式部分。例如,“500[1-5]”将变为“500X”,或“20[1-9]00[89]”将变为“20X00X”,依此类推
  • 获取“最后”4个字符+正则表达式字符的长度

    var len = lastNChars + pattern.Length - Regex.Replace(pattern, @"\[[^\]]+\]", "X").Length;
    
    因此,对于模式20[1-9]00[89],上述公式转化为“len=4+13-6”,或11

  • 使用上面的len变量,获取一个子字符串,该子字符串表示电话号码的“最后”4个号码,即使使用正则表达式字符也是如此。原来的字符串=“20[1-9]00[89]”,而新的子字符串=“[1-9]00[89]”(20现在消失了)

  • 枚举并将数组值与子字符串正则表达式模式进行比较。[9999]不匹配正则表达式模式,[9998]不匹配…[9997]不匹配…啊哈!9009场比赛!我得到的第一场比赛是可能的最大的正则表达式比赛,这是我想要的
  • 因此,每个正则表达式模式都已转换为其最大可能的匹配模式。现在我们可以使用C#/LINQ/其他内置方法,这些方法可以为我们按这些子正则表达式匹配进行排序
    谢天谢地,我只处理数字。如果我尝试对实际是单词/有字母字符的正则表达式模式进行排序,那会困难得多,而且数组会更大(我想)。

    如果不全部枚举并测试,很难找到与正则表达式匹配的示例字符串。我也不认为你能找到一个对正则表达式进行排序的C#库。但是,对于不包含量词的模式的特殊情况(例如
    [0-9]+
    [3-6]{4}
    ),您可以解决此问题,如下所示:

    const int lastNChars = 4;
    var patterns = new string[]{@"8062", @"\+13066598273", @"4083100", 
            @"408320[0-3]", @"408320[4-6]", @"752[234569]", 
            @"\+13066598305", @"8059"};
    var range = Enumerable.Range(0, (int) Math.Pow(10, lastNChars))
                .Reverse().ToArray();
    
    var sortedPatterns = patterns.OrderBy(pattern=> {
        var len = lastNChars + pattern.Length 
                - Regex.Replace(pattern, @"\[[^\]]+\]", "X").Length;
    
        // Get the biggest number in range that matches this regex:
        var biggestNumberMatched = range.FirstOrDefault(x => 
            Regex.IsMatch(x.ToString(new String('0', lastNChars)), 
                        pattern.Substring(pattern.Length - len, len))
        );
        return biggestNumberMatched;
    }).ToArray();
    

    之后,
    sortedPatterns
    包含所需的输出。

    如果不全部枚举并测试,很难找到与正则表达式匹配的示例字符串。我也不认为你能找到一个对正则表达式进行排序的C#库。但是,对于不包含量词的模式的特殊情况(例如
    [0-9]+
    [3-6]{4}
    ),您可以解决此问题,如下所示:

    const int lastNChars = 4;
    var patterns = new string[]{@"8062", @"\+13066598273", @"4083100", 
            @"408320[0-3]", @"408320[4-6]", @"752[234569]", 
            @"\+13066598305", @"8059"};
    var range = Enumerable.Range(0, (int) Math.Pow(10, lastNChars))
                .Reverse().ToArray();
    
    var sortedPatterns = patterns.OrderBy(pattern=> {
        var len = lastNChars + pattern.Length 
                - Regex.Replace(pattern, @"\[[^\]]+\]", "X").Length;
    
        // Get the biggest number in range that matches this regex:
        var biggestNumberMatched = range.FirstOrDefault(x => 
            Regex.IsMatch(x.ToString(new String('0', lastNChars)), 
                        pattern.Substring(pattern.Length - len, len))
        );
        return biggestNumberMatched;
    }).ToArray();
    

    之后,
    sortedPatterns
    包含所需的输出。

    这里有一个解决方案,归功于Matt Hamilton:

    var pList=new List()
    { 
    "01233[0-3]", "12356[1-3]", "55555[7-9]"
    };
    变量配对=
    pList.Select(x=>
    新的KeyValuePair
    (Int32.Parse(新字符串((新字符串(x.Where(Char.IsDigit).Reverse().ToArray()))
    .Substring(0,4).Reverse().ToArray()),x);
    var pairedOrdered=paired.OrderByDescending(x=>x.Key);
    foreach(成对排序中的var kvp)
    {
    WriteLine(“Key:{0}值:{1}”,kvp.Key,kvp.Value);
    }
    
    输出:

    键:5613值:12356[1-3]

    键:5579值:55555[7-9]

    键:3303值:01233[0-3]


    这里有一个解决方案,归功于Matt Hamilton:

    var pList=new List()
    { 
    "01233[0-3]", "12356[1-3]", "55555[7-9]"
    };
    变量配对=
    pList.Select(x=>
    新的KeyValuePair
    (Int32.Parse(新字符串((新字符串(x.Where(Char.IsDigit).Reverse().ToArray()))
    .Substring(0,4).Reverse().ToArray()),x);
    var pairedOrdered=paired.OrderByDescending(x=>x.Key);
    foreach(成对排序中的var kvp)
    {
    WriteLine(“Key:{0}值:{1}”,kvp.Key,kvp.Value);
    }
    
    输出:

    键:5613值:12356[1-3]

    键:5579值:55555[7-9]

    键:3303值:01233[0-3]


    这就是我要找的,非常感谢!现在我正在为我自己的MVC项目调整这个。我也没搞错,发现我的数字列表中有少于4位数的数字。我可能会暂时把它们改成4位数,比如把“40”改成“0040”。这就是我想要的,谢谢!现在我正在为我自己的MVC项目调整这个。我也没搞错,发现我的数字列表中有少于4位数的数字。我可能会暂时把它们改成4位数,比如把“40”改成“0040”