2009-11-10 128 views
0

我在PHP,看起來在格式的日期正則表達式YYYY-MM-DD正則表達式匹配YYYY-MM-DD格式的日期

我所擁有的是:[\d]{4}-[\d]{2}-[\d]{2}

我使用preg_match來測試日期,問題是2009-11-10工作,但2009-11-1033434也適用。我已經完成了一段正則表達式,我該如何確保它停在正確的位置?我試過做/([\d]{4}-[\d]{2}-[\d]{2}){1}/,但它返回相同的結果。

任何幫助將不勝感激。

回答

9

你需要的是錨,特別是^$。前者匹配字符串的開始,後者匹配結束。

我想說的另一點是[]是不必要的。 \d在字符範圍之外保留其含義。

所以你的正則表達式應該是這樣的:/^\d{4}-\d{2}-\d{2}$/

1

您可能想要在表達式上放置錨點。 即

^[\d]{4}-[\d]{2}-[\d]{2}$ 

注意脫字符號和美元符號。

3

您如何期待您的日期被終止?

如果行尾,那麼後面的$應該做的伎倆。

如果是非數字字符,那麼下面的負數assertion(?!\d)也會起作用。

+2

使用[^ \ d]將捕捉到的非數字字符。使用負向前瞻斷言會更好,如'(?!\ d)' – 2009-11-10 22:37:28

+0

啊。當然。糾正。謝謝。 – 2009-11-10 22:38:47

0

你可以嘗試把既有「^」和你表達的開始和結束一個「$」符號:

/^[\d]{4}-[\d]{2}-[\d]{2}$/ 

匹配的開始和字符串分別到底是哪。

1

[\d]{4}-[\d]{2}-[\d]{2}?

其中問號表示「非貪婪」

+0

'\ d {2}?'和'\ d {2}'是相同的。 '{2}'已經明確地說過這些原子的匹配2,所以這個組的貪婪沒有效果。 – 2009-11-10 22:51:59

+0

@Kevin B:thx。但是爲什麼$ EOL在原來的「2009-11-1033434」示例中運行,而不是「{2}」? – 2009-11-10 23:11:41

+0

因爲$匹配字符串的末尾。 '\ d {2}'匹配兩個數字,但並不是說該字符串必須在那裏停止。 '\ d {2} $'說:「匹配兩位數,然後確保我們已經到達字符串的末尾」。 那麼,更具體的^和$實際上與多行上下文中的行開始/結束匹配,但是在非多行上下文中,它們匹配字符串開始/結束。還有'\ A'和'\ z'(或'\ Z'),它總是匹配字符串的開始/結束,而不管多行上下文。 – 2009-11-11 01:06:02

1

你可能想向前看斷言(假設你的引擎支持他們,PHP /浸漬/ PCRE一樣)

向前看斷言(或肯定的斷言)允許你說「它應該跟隨X,但X不應該是匹配的一部分)嘗試以下語法

\d{4}-\d{2}-\d{2}(?=[^0-9]) 

的說法是這部分

(?=[^0-9]) 

它說:「我正則表達式之後,下一個字符不能是數字」

如果沒有得到你想要/需要什麼,後一個例子你的輸入和你的PHP代碼不工作。這兩個項目對調試這些問題非常有用。

+0

如果遇到字符串的結尾,則肯定前瞻斷言將失敗。使用「(?!\ d)」這樣的負向前瞻斷言更好。 – 2009-11-10 22:52:47

3
^20[0-2][0-9]-((0[1-9])|(1[0-2]))-([0-2][1-9]|3[0-1])$ 

我加一點額外的檢查,以幫助的MMDD問題由用戶使用混合起來。這沒有捕捉到所有日期mixups,但確實保持20002029之間的YYYY一部分,MM12之間0131之間01DD

+0

這很有用,但有一個小錯誤 - 它排除了第10天和第20天。它應該使用:'^ 20 [0-2] [0-9] - ((0 [1-9])|(1 [0 -2])) - (0 [1-9] | [1-2] [0-9] | 3 [0-1])$' – Fraser 2017-03-11 15:54:41