2016-08-24 86 views
1

給定一個正則表達式模式的數字列表,按照該數字值中的最後4個數字對它們進行排序。訂購一組正則表達式模式或獲取最大的正則表達式匹配

我有一個正則表達式(電話號碼)模式列表,我試圖按最後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 C#項目中對它們進行排序。在SQL中,我可以使用ORDER BY RIGHT(pattern,4),或者在C#MVC中,我可以使用對我的IQueryable列表進行排序。patterns = patterns.OrderByDescending(s => s.Substring(... etc ... ))

模式有點困難。括號算作字符,所以按最後4個字符排序也不起作用。

在C#,MVC或SQL中是否有任何內置實用程序允許我將正則表達式模式轉換爲儘可能大的匹配?

  • 給定一個正則表達式模式,返回匹配我的條件的最大匹配正則表達式。例如,如果我有模式4 [12] 00 [1-3],我會得到6個可能的結果:41001,41002,41003,42001,42002,42003。然後我可以得到最大的數字,並使用爲了在我原來的正則表達式列表。
    • 正則表達式模式不包含任何類似*或+的特殊字符,可能會導致無限組合。
  • 有可能是一個C#庫,完全按照我的要求,排序正則表達式模式字符串。

編輯:

我已經接受了迭戈的答案,但我花了一些時間來環繞它我的頭。對於誰想要知道它在做什麼其他的讀者來說,這是我認爲迭戈是這樣做的:

  1. 做了一系列整數的,開始於9999,回0 [9999]一路,[9998] ,[9997] ... [0]。
  2. 用單個字符替換字符串的正則表達式部分。例如,「500 [1-5]」將變爲「500X」,或「20 [1-9] 00 [89]」變爲「20X00X」,等等。
  3. 獲取「最後」4個字符+正則表達式字符的長度。

    var len = lastNChars + pattern.Length - Regex.Replace(pattern, @"\[[^\]]+\]", "X").Length; 
    

    所以對於圖案20 [1-9] 00 [89],在上述式轉換爲 「LEN = 4 + 13 - 6」,或11

  4. 使用來自LEN可變上面,得到表示電話號碼的「最後」4個數字的子字符串,即使是正則表達式字符。原始字符串=「20 [1-9] 00 [89]」,而新的子字符串=「[1-9] 00 [89]」(現在20不見了)

  5. 枚舉通過並比較數組值到子字符串正則表達式模式。 [9999]與正則表達式模式不匹配,[9998]不匹配... [9997]不匹配...哈哈! 9009場比賽!我得到的第一場比賽是儘可能最大化的正則表達式匹配,這正是我想要的。
  6. 因此,每個正則表達式模式已被轉換爲其最大可能的匹配模式。現在我們可以使用C#/ LINQ /其他內置方法,可以通過這些子正則匹配對我們進行排序!

感謝上帝我只處理數字。如果我正在嘗試對實際上是單詞/具有字母字符的排序正則表達式模式進行排序,那將會更加困難,並且該數組將會更大(我認爲)。

回答

0

很難找到匹配正則表達式的示例字符串,而不枚舉它們並對其進行測試。我也不認爲你將能夠找到一個排序正則表達式的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包含所需的輸出。

+0

這就是我一直在尋找的,非常感謝!現在我正在爲適應我自己的MVC項目調整這個過程。我也蠢蠢欲動,發現我的數字列表包含少於4位數字的數字。我可能會處理這個問題,只是暫時強迫他們變成4位數字,就像'40'變成'0040'一樣。 – JTsoi

0

這裏是一個解決方案,學分馬特漢密爾頓從這個question

var pList = new List<string>() 
{ 
    "[0-3]", "12356[1-3]", "55555[7-9]" 
}; 
var paired = 
    pList.Select(x => 
     new KeyValuePair<int, string> 
     (Int32.Parse(new String((new String(x.Where(Char.IsDigit).Reverse().ToArray())) 
     .Substring(0, 4).Reverse().ToArray())), x)); 

var pairedOrdered = paired.OrderByDescending(x => x.Key); 
foreach(var kvp in pairedOrdered) 
{ 
    Console.WriteLine("Key: {0} Value: {1}", kvp.Key, kvp.Value); 
} 

輸出:

密鑰:5613值:12356 [1-3]

密鑰:5579 Value:55555 [7-9]

Key:3303 Value:[0-3]