2013-09-27 120 views
2

我有一個正則表達式設置爲匹配US格式的日期和時間。它看起來像這樣:匹配部分的可選部分

/(\d{1,2})\/(\d{1,2})\/(\d{2,4}) (\d{1,2}):(\d{1,2})(am|pm|AM|PM|Am|Pm)/ 

但是,我需要它也匹配日期,不包含時間組件。

如何修改這一點,因此,如果它是一個日期,我得到的3場比賽,如果它是一個日期 - 時間,我送六?

回答

2

Group的時間,並使其optional

/(\d{1,2})\/(\d{1,2})\/(\d{2,4})(?: (\d{1,2}):(\d{1,2})(am|pm|AM|PM|Am|Pm))?/ 

?:抑制拍攝,讓你不附加組結束了,如果時間存在。

另外,如果你不是太挑剔允許aMpM,你可以用相當不區分大小寫的修改簡化:

/(\d{1,2})\/(\d{1,2})\/(\d{2,4})(?: (\d{1,2}):(\d{1,2})([ap]m))?/i 

事實上,使用?你甚至可以縮短圖形另外, (因爲\d?短於{1,2}

/(\d\d?)\/(\d\d?)\/(\d{2,4})(?: (\d\d?):(\d\d?)([ap]m))?/i 

不過請注意,在任何情況下,你仍然會得到6組(7如果算上整個匹配) - 這是菊ST,最後三會undefined

> groups = '11/11/11'.match(/(\d{1,2})\/(\d{1,2})\/(\d{2,4})(?: (\d{1,2}):(\d{1,2})([ap]m))?/i) 
["11/11/11", "11", "11", "11", undefined, undefined, undefined] 

同樣使用exec代替時發生。但這些都是容易的,如果需要過濾掉:

> groups.filter(function(capture) { 
     return typeof capture !== 'undefined'; 
    }); 
["11/11/11", "11", "11", "11"] 

或在此情況下(因爲你永遠不能擁有空字符串作爲捕獲):

> groups.filter(function(capture) { 
     return capture; 
    }); 
["11/11/11", "11", "11", "11"] 
2

使用?時間正則表達式,包裝與(?:)非捕獲組。

/(\d{1,2})\/(\d{1,2})\/(\d{2,4})(?:\s+(\d{1,2}):(\d{1,2})(am|pm|AM|PM|Am|Pm))?/ 

請注意,文字空間已被替換爲\s+

+ - 匹配1個或多個

* - 匹配0個或更多

? - 匹配0或1

+0

雖然沒有更好的解決方案,請注意,這不會產生只有4個元素的數組。 –

+0

4個要素?對不起,沒有得到你。那問題在哪裏? – jkshah

+0

OP希望「只有3個匹配」,所以我認爲值得指出的是,在'match'或'exec'中使用模式時,您獲得的數組仍然具有相同數量的元素。只是它們中的一些將會是'未定義的'。 –

2

您可以使用此:

/(\d{1,2})\/(\d{1,2})\/(\d{2,4})(?: (\d{1,2}):(\d{1,2})(am|pm|AM|PM|Am|Pm))?/ 

甚至縮短您的正則表達式:

/(\d{1,2})\/(\d{1,2})\/(\d{2,4})(?: (\d{1,2}):(\d{1,2})([ap]m))?/i 

我包裹的空間和時間成非捕獲組,把一個用於? 0或1次發生,使時間可選的。

的字符類[ap]比賽無論是ap以來都ampm結束與m,你可以簡單地使用[ap]m和不區分大小寫的修改,使[ap]m匹配大寫和小寫字符。

+1

雖然沒有更好的解決方案,但請注意,這不會產生只有4個元素的陣列。此外,你放棄捕獲am/pm'位。 –

+0

在縮短xD期間一定發生過謝謝! – Jerry