php正则表达式 匹配日期,正则表达式-正则表达式以匹配有效日期
我登陸這里是因為這個問題的標題很寬泛,我一直在尋找可用于匹配特定日期格式(例如OP)的正則表達式。 但是我隨后發(fā)現(xiàn),正如許多答案和評論已全面突出顯示的那樣,在提取與質量低劣或非結構化源數(shù)據(jù)混在一起的日期時,存在許多陷阱使構建有效模式變得非常棘手。
在探索問題時,我想出了一個系統(tǒng),使您可以通過將四個在分隔符上匹配的更簡單的子表達式以及順序中的年,月和日字段的有效范圍排列在一起,來構建正則表達式 您需要。
這些是 :-
定界符
[^\w\d\r\n:]
這將匹配不是單詞字符,數(shù)字字符,回車符,換行符或冒號的任何內容。 冒號必須存在,以防止在日期類似的時間匹配(請參閱我的測試數(shù)據(jù))
您可以優(yōu)化模式的這一部分以加快匹配速度,但這是檢測大多數(shù)有效定界符的良好基礎。
注意; 它將匹配帶有混合定界符(例如2 / 12-73)的字符串,該定界符可能實際上不是有效日期。
年值
(\d{4}|\d{2})
這與兩位或四位數(shù)字匹配,在大多數(shù)情況下是可以接受的,但是如果您要處理的是0-999年或9999年以后的數(shù)據(jù),則需要決定如何處理,因為在大多數(shù)情況下為1,3 或> 4位數(shù)字的年份是垃圾。
月值
(0?[1-9]|1[0-2])
匹配1到12之間的任何數(shù)字,帶或不帶前導零-注意:0和00不匹配。
日期值
(0?[1-9]|[12]\d|30|31)
匹配1到31之間的任何數(shù)字,帶或不帶前導零-注意:0和00不匹配。
此表達式匹配日期,月份,年份格式的日期
(0?[1-9]|[12]\d|30|31)[^\w\d\r\n:](0?[1-9]|1[0-2])[^\w\d\r\n:](\d{4}|\d{2})
但它也可以匹配某些年,月日期。 還應與邊界運算符一起進行預訂,以確保選擇了整個日期字符串,并防止從格式不正確的數(shù)據(jù)(即沒有邊界標簽的數(shù)據(jù)中提取有效的子日期)匹配20/12/194和20/12/19以及 101/12/1974比賽為01/12/1974
將下一個表達式的結果與上一個表達式的結果與廢話部分中的測試數(shù)據(jù)進行比較(如下)
\b(0?[1-9]|[12]\d|30|31)[^\w\d\r\n:](0?[1-9]|1[0-2])[^\w\d\r\n:](\d{4}|\d{2})\b
此正則表達式?jīng)]有驗證,因此將匹配格式正確但無效的日期(例如31/02/2001)。 那是一個數(shù)據(jù)質量問題,正如其他人所說的,您的正則表達式不需要驗證數(shù)據(jù)。
因為您(作為開發(fā)人員)不能保證源數(shù)據(jù)的質量,所以您確實需要執(zhí)行和處理代碼中的其他驗證,因此,如果嘗試匹配和驗證RegEx中的數(shù)據(jù),它將變得非常混亂,并且變得很難 沒有非常簡潔的文檔支持。
垃圾進垃圾出。
話雖如此,如果您確實有日期值各不相同的混合格式,則必須盡可能地提取; 您可以像這樣將兩個表達式組合在一起;
此(災難性)表達式匹配DMY和YMD日期
(\b(0?[1-9]|[12]\d|30|31)[^\w\d\r\n:](0?[1-9]|1[0-2])[^\w\d\r\n:](\d{4}|\d{2})\b)|(\b(0?[1-9]|1[0-2])[^\w\d\r\n:](0?[1-9]|[12]\d|30|31)[^\w\d\r\n:](\d{4}|\d{2})\b)
但是您將無法確定1973年6月9日這樣的日期是9月6日還是6月9日。 我正在努力思考這樣一種情況,即該情況不會在某個地方造成問題,這是不好的做法,您不必這樣處理-找到數(shù)據(jù)所有者并用治理錘來打擊他們 。
最后,如果要匹配不帶分隔符的YYYYMMDD字符串,則可以消除一些不確定性,表達式如下所示
\b(\d{4})(0[1-9]|1[0-2])(0[1-9]|[12]\d|30|31)\b
但請再次注意,它將匹配格式正確但無效的值,例如20010231(2月31日!):)
測試數(shù)據(jù)
在對該線程中的解決方案進行實驗時,我最終得到了一個測試數(shù)據(jù)集,其中包含各種有效和無效日期,以及一些您可能希望或不希望匹配的棘手情況,例如,可以匹配為日期和日期的時間 多行。
我希望這對某人有用。
Valid Dates in various formats
Day, month, year
2/11/73
02/11/1973
2/1/73
02/01/73
31/1/1973
02/1/1973
31.1.2011
31-1-2001
29/2/1973
29/02/1976
03/06/2010
12/6/90
month, day, year
02/24/1975
06/19/66
03.31.1991
2.29.2003
02-29-55
03-13-55
03-13-1955
12\24\1974
12\30\1974
1\31\1974
03/31/2001
01/21/2001
12/13/2001
Match both DMY and MDY
12/12/1978
6/6/78
06/6/1978
6/06/1978
using whitespace as a delimiter
13 11 2001
11 13 2001
11 13 01
13 11 01
1 1 01
1 1 2001
Year Month Day order
76/02/02
1976/02/29
1976/2/13
76/09/31
YYYYMMDD sortable format
19741213
19750101
Valid dates before Epoch
12/1/10
12/01/660
12/01/00
12/01/0000
Valid date after 2038
01/01/2039
01/01/39
Valid date beyond the year 9999
01/01/10000
Dates with leading or trailing characters
12/31/21/
31/12/1921AD
31/12/1921.10:55
12/10/2016 8:26:00.39
wfuwdf12/11/74iuhwf
fwefew13/11/1974
01/12/1974vdwdfwe
01/01/99werwer
12321301/01/99
Times that look like dates
12:13:56
13:12:01
1:12:01PM
1:12:01 AM
Dates that runs across two lines
1/12/19
74
01/12/19
74/13/1946
31/12/20
08:13
Invalid, corrupted or nonsense dates
0/1/2001
1/0/2001
00/01/2100
01/0/2001
0101/2001
01/131/2001
31/31/2001
101/12/1974
56/56/56
00/00/0000
0/0/1999
12/01/0
12/10/-100
74/2/29
12/32/45
20/12/194
2/12-73
總結
以上是生活随笔為你收集整理的php正则表达式 匹配日期,正则表达式-正则表达式以匹配有效日期的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 另存为在哪里(电脑另存为桌面不见了怎么办
- 下一篇: php基础遍历,php 数据遍历