2014-03-03 49 views
2

我的問題:我發現這個練習非常具有挑戰性。我很喜歡出生日期。使用正則表達式驗證出生日期

挑戰:試着拿出正則表達式來驗證下面的文本字符串(不要擔心不區分大小寫):

  1. 名字 - 應該由標準的英文字母和一個之間十個字符的長度。
  2. 中間首字母 - 應由標準英文字母組成,且長度只有一個字符。
  3. 姓氏 - 應由標準英文字母加撇號和長度在兩到十個字符之間。
  4. 出生日期 - 應該在1/1/1900和12/31/2099之間,並且應該是以下日期格式之一:dd/mm/yyyy,dd-mm-yyyy或dd.mm.yyyy 。

我能夠拿出前三個名字。但我被困在出生日期。

"^[a-z]{1,10}$", // First name 
    "^[a-z]$",  // Middle initial 
    "^[a-z']{2,10}$", // Last name 

請幫幫我。

+0

對日期格式的要求有點混亂。在爲可接受的範圍命名的日期中,您在日期之前有一個月的地方(由12/31表示),但是在日期格式中,日期在前。此外,最早的日期(1/1/1900)寫爲d/m/yyyy。正則表達式是否需要匹配月份和日期的單個數字值,或者該日期是否顯示爲01/01/1900? – CAustin

+0

就在昨天,我寫了一篇有關匹配數字範圍與正則表達式的博客文章,該文章適用於問題的年份(儘管我承認,1900年至2099年非常簡單,正如您的一些答案中所述):http: //aliteralmind.wordpress.com/2014/03/02/regex_numeric_range – aliteralmind

+0

這不是微不足道的,看到我的答案在這裏:http://stackoverflow.com/a/3873172/372239 – Toto

回答

1

對於正則表達式的日期,看到鏈接:Regex Tutorial

但我認爲,例如將工作。

"^(0[1-9]|1[012])[-/.](0[1-9]|[12][0-9]|3[01])[-/.](19|20)\\d\\d$" 
+0

請求的格式是'dd/mm/yyyy'而不是'mm/dd/yyyy'。它也匹配'02/31/1900' – Toto

2
/^((1[0-2])|[1-9])[/-.](3[0-1]|[1-2]\d|[1-9])[/-.][19|20]\d{2}$/ 
+2

這是如何防止10/10-2010? – xp500

+0

它沒有。但是你需要寫一個相當漫長而又醜陋的正則表達式來防止這種情況。 –

+2

或使用[backrefs](http://www.regular-expressions.info/backref.html)(假設引擎支持它們) – xp500

1

對於誕生之日起,你匹配的字符串的開始,那麼對你來說有一個捕獲組匹配的01一個,02,03,04,05,06,07月份部分, 08,09,10,11或12,然後是另一個捕獲組以匹配任何一個 - ,/

對於天數部分,您需要捕獲組以匹配01,02,... 29,30或31之一,隨後捕獲組來匹配任一 - ,/或出生

日期:

"^(0[1-9]|1[012])[-/.](0[1-9]|[12][0-9]|3[01])[-/.](19|20)\\d\\d$" 
+2

這是如何防止10/10-2010? – xp500

+0

請求的格式是'dd/mm/yyy'而不是'mm/dd/yyyy'。它也匹配'02/31/1900' – Toto

4

有幾個項目來處理這裏:

  1. 一天,一個月,一年只驗證適當的值值
  2. 驗證正確的元素是在正確的位置
  3. 驗證了分隔符匹配
  4. 驗證,這是一個實際的日期

第一個看起來可能與分組和或。例如,你可以從1-12相匹配的所有值:

(?:0[1-9]|1[12]) 

而且1900年至2099年與

(?:19|20)\d\d 

第二位只是把模式的適當部位在的事正確的位置。

第三部分可以用反向引用完成。首先,你有一個亞組的分隔符匹配,像這樣:

([\/.-]) 

接下來你需要確保你以後的比賽中再次得到相同的角色。這是通過指定一個反斜槓,然後指定組的編號完成的。例如:

\1 

最後,我們想確保沒有人規定1925年6月31日或1994年2月30日這是很可怕的正則表達式來完成,並應儘快發送給我們運行了小山。正則表達式不是解決這個問題的正確方案。 所以留下的是,除了能解決前三個部分用正則表達式看起來像:

^(?:0[1-9]|[12]\d|3[01])([\/.-])(?:0[1-9]|1[12])\1(?:19|20)\d\d$ 

注意使用:使某些分組沒有得到一個子匹配,這樣我們只需要處理我們感興趣的submatches。不是嚴格要求,但它使得它更清晰。如果你將這些分離出來,分隔符將成爲第二個分組,而不是第一個分組。

1

嘗試

/^((1[0-2])|[1-9])[/-.](3[0-1]|[1-2]\d|[1-9])[/-.][19|20]\d{2}$/ 
+1

請添加一些你正在做的事情的解釋。 –

+0

請求的格式是'dd/mm/yyyy'而不是'mm/dd/yyyy'。它也匹配'02/31/1900' – Toto

1

對於誕生之日起,比賽在字符串的開始,那麼月供部分你有一個捕獲組匹配的01一個,02,03,04 ,05,06,07,08,09,10,11或12,然後是另一個捕獲組以匹配 -/

我認爲這個例子會起作用。

"^(0[1-9]|1[012])[-/.](0[1-9]|[12][0-9]|3[01])[-/.](19|20)\\d\\d$"