2012-06-07 47 views
1

請注意,這不是一個問題什麼是代碼的最佳方式做日期驗證 這是一個問題關於學習更多有關正則表達式通過一些摸索與其他國家人民的INSITE 謝謝。正則表達式完整日期驗證

最近我一直在用正則表達式做很多工作(很坦白地說,我吸吮他們)我雖然學習了很多,但我想知道如果任何人都可以就特定的正則表達式給出他們的專家意見。

現在我正在將一個相當大的項目遷移到使用.NET 4.0它有很多解析和數據操作方法跨越很多類和名稱空間......但大多數並非所有的解析和驗證已經完成了與大量的IndexOf()調用大笨重的循環。

我一直使用相當成功的正則表達式,LINQ和擴展方法的組合,大大簡化和澄清解析和驗證方法。

試錯法和RegexBuddy在學習曲線方面的幫助非常大。

現在到我的實際問題。

我是在更新一個簡單的日期驗證工作,雖然這是一個非常非常寬鬆驗證

private static bool isLikeVCardDate(string value_Renamed) 
{ 
    if (value_Renamed == null) 
    { 
    return true; 
    } 
    // Not really sure this is true but matches practice 
    // Mach YYYYMMDD 
    if (isStringOfDigits(value_Renamed, 8)) 
    { 
    return true; 
    } 
    // or YYYY-MM-DD 
    return value_Renamed.Length == 10 && value_Renamed[4] == '-' && value_Renamed[7] == '-' && isSubstringOfDigits(value_Renamed, 0, 4) && isSubstringOfDigits(value_Renamed, 5, 2) && isSubstringOfDigits(value_Renamed, 8, 2); 
} 

如果我想的

private static bool isLikeVCardDate(string value_Renamed) 
{ 
    return Regex.IsMatch(value_Renamed, @"\d{4}-?\d{2}-?d{2}"); 
} 

一個簡單的正則表達式匹配的功能將滿足要求

但它讓我思考如何去驗證日期是完全有效的日期,閏年,整個9碼的月份的天數

在知道還有其他職位有關日期驗證與正則表達式我不感興趣的人直接給我一個答案我有它的工作我想知道是否有任何知識任何人都可以告訴我如何也許做得更好或改進。

提醒你,我知道這可能是不使用正則表達式的實際應用的最好的例子,請記住,我是想在這裏學習,希望得到一些幫助

這裏是我想出了正則表達式

一些注意事項爲了簡化閱讀,我將它粘貼在「標籤」視圖中,實際的正則表達式沒有空格或換行符。

此外的一切,是不是一個命名捕獲組是一個非捕獲組(我離開了這一點就節約空間,因爲我只是想讓人們對正則表達式的分析)

(
(?<YEAR>((([0][48])|([13579][26])|([2468][048]))00)|(\d{2}(([0][48])|([13579][26])|([2468][048])))) 
-? 
(
    (
    (?<MONTH>(0[13578])|(1[02])) 
    -? 
    (?<DAY>(0[1-9])|([12][0-9])|(3[01])) 
) 
    | 
    (
    (?<MONTH>(0[469])|11) 
    -? 
    (?<DAY>(0[1-9])|([12][0-9])|30) 
) 
    | 
    (
    (?<MONTH>02) 
    -? 
    (?<DAY>(0[1-9])|([12][0-9])) 
) 
) 
) 
| 
(
(?<YEAR>\d{4}) 
-? 
(
    (
    (?<MONTH>(0[13578])|(1[02])) 
    -? 
    (?<DAY>(0[1-9])|([12][0-9])|(3[01])) 
) 
    | 
    (
    (?<MONTH>(0[469])|11) 
    -? 
    (?<DAY>(0[1-9])|([12][0-9])|30) 
) 
    | 
    (
    (?<MONTH>02) 
    -? 
    (?<DAY>(0[1-9])|(1[0-9])|(2[0-8])) 
) 
) 
) 

這裏是我的思維過程

  1. 天是相對於月4,6,9,11是三十天| 1,3,5,7,8,10,12有31和2具有28或29

  2. 閏年是被4整除,除非它是通過100整除則僅當也被400整除

    1. 在此基礎上,事實上,任何數目被4整除,如果最後兩位數字作爲一個數是被4整除

    2. 從4寫出的數字 - 96 I使用的0的重複圖案(4, 8),{甚至> 0}(0,4,8)和{奇數}(2,6)

    3. 由於測試400年閏年給我們的第一個2個位數的年份是適用的,我們可以我們的#2以上

  3. 由於閏年的要求正則表達式需要2所獨立的捕獲的日期的同一模式在閏年和日期不在閏年。

現在我所有的假設可能僅僅是錯誤的,只是簡單的在那裏,但它是我能想出多少我理解正則表達式到目前爲止

再次聲明,我只是在尋找有利於提高在正則表達式,因爲我迫切需要讓我的頭纏繞它。

非常感謝任何花時間閱讀這個問題的人。

+2

爲什麼不使用'DateTime.TryParse'?特別是因爲它看起來像你有特定的日期格式。並非所有事情都需要通過正則表達式完成;) – rikitikitik

+0

不要重新發明輪子。使用你的語言的日期/時間庫。 –

+0

第一個「正則表達式」僅僅是爲了說明如果現有的「驗證」足以滿足原始方法對驗證日期的實際價值的作用。它檢查的是有4個數字後跟隨一個可選 - 2個數字後跟一個可選 - 後跟2個數字。 – TofuBug

回答

2

我明白你在做這個作爲一個練習,瞭解正則表達式,所以你可能會喜歡的工作出在回答這些問題的例子是如何工作的:

當然,對學習正則表達式的最重要的教訓之一是,當不要使用它們。因此,我認爲您可能很難獲得關於您發佈的示例的詳細反饋。這裏帶回家的教訓是,雖然有些人喜歡寫複雜的正則表達式,但很少有人喜歡閱讀(或擴展或修復)他們。

+0

我非常瞭解人們的一些想法,當我剛上小學的時候,我剛剛開始編程時就立即採取了一些措施(BASICA any?:-P)。然而,有時候,概念會讓我感到沮喪,而我爲了理解他們而苦苦掙扎。早在當時,就是如何正確管理C和C++中的內存。現在我可以圍繞Expression樹編寫代碼圈,使用高級併發數據結構輕鬆工作,甚至可以處理閉包和函數式編程。但是Regex只是把我搞糊塗了。出於這個原因,我需要非常人爲的例子來幫助我。 – TofuBug

+0

另外我喜歡成爲這個社區的一部分,因爲它是如此巨大的知識來源 – TofuBug