我想從日期時間偏移值中去掉(CDT)
。我寫了下面的簡單的正則表達式來這樣做,它的工作原來是預期的,但寫完後我仍然想知道爲什麼它可以工作。爲什麼2012年的結果不會停止?爲什麼這個正則表達式工作?
原始字符串:"Thu, 02 Aug 2012 07:42:02 -1525 (CDT)"
正則表達式:.*\d{4}
結果:"Thu, 02 Aug 2012 07:42:02 -1525"
我想從日期時間偏移值中去掉(CDT)
。我寫了下面的簡單的正則表達式來這樣做,它的工作原來是預期的,但寫完後我仍然想知道爲什麼它可以工作。爲什麼2012年的結果不會停止?爲什麼這個正則表達式工作?
原始字符串:"Thu, 02 Aug 2012 07:42:02 -1525 (CDT)"
正則表達式:.*\d{4}
結果:"Thu, 02 Aug 2012 07:42:02 -1525"
的量詞*
是貪婪的。這意味着它會盡可能匹配。
這就是爲什麼\d{4}
匹配1525
和.*
匹配之前的字符。
如果您使用惰性量詞*?
,那麼在嘗試更長的序列之前,它將首先與最少的字符數匹配。在這種情況下,它會讓\d{4}
與2012
匹配。
圖案.*\d{4}
匹配後跟4個數字的零個或多個字符(貪婪地)的任何序列。
它的工作原理是匹配所有字符串中的最後四位數字(1525
),並忽略字符串的其餘部分。
請注意您的圖案有點危險。如果輸入缺少的時區偏移,其結果必然是顯著不同:
Thu, 02 Aug 2012 07:42:02
Thu, 02 Aug 2012
.*
是貪婪因此它會在查找最後四位數字之前消耗盡可能多的字符\d{4}
。
在一些正則表達式引擎(如Perl),您可以添加?
指定非貪婪比賽:.*?\d{4}
,這應該與2012年
的sybmol *被說成是「貪婪」。這意味着在強制匹配下面的標記之前,它將匹配前面字符的儘可能多的字符。 1525是可以滿足\ d {4}的最後一個可能部分,所以。*將所有東西都抓到1525.
?通常作爲一個非貪婪的標誌。
它的工作原理是.*
是greedy。
這意味着.*
會在做其他事情之前儘可能匹配。
當正則表達式的應用,.*
整個事情相匹配,因爲它是貪婪:
星期四,2012年8月2日7時42分02秒-1525(CDT)
然後嘗試以匹配\d{4}
,但不幸的是,它不匹配任何東西,因爲它在最後。因此,正則表達式(在.*
部分)將回溯(回去給回什麼是先前已經匹配)一次,每次一個字符,並檢查\d{4}
:
星期四,2012年8月2日07 :42:02 -1525(CDT)[無匹配]
星期四,2012年8月2日7時42分02秒-1525(CD T)[無匹配]
星期四,2012年8月2日07:42:02 -1525(C DT)[No ma TCH]
星期四,2012年8月2日7時42分02秒-1525( CDT)[無匹配]
星期四,2012年8月2日7時42分02秒-1525(CDT)[不比賽]
星期四,2012年8月2日7時42分02秒-1525(CDT)沒有匹配]
...
星期四,2012年8月2日7時42分02秒 - 1525(CDT)
在這一點上,它能夠匹配\d{4}
,所以這就是它會做:
星期四,2012年8月2日7時42分02秒-1525( CDT)
而且由於正則表達式中沒有別的東西,所以會在這裏結束。
正則表達式引擎步驟:
matches | pattern | description
---------------------------------------+---------+-------------------------------
Thu, 02 Aug 2012 07:42:02 -1525 (CDT) | .* | match all possible characters
---------------------------------------+---------+-------------------------------
Thu, 02 Aug 2012 07:42:02 -1525 (CDT) | \d{4} | the RE doesn't find the 4 digits
---------------------------------------+---------+-------------------------------
Thu, 02 Aug 2012 07:42:02 -1525 (CDT | \d{4} | the RE backtracks char by char
---------------------------------------+---------+-------------------------------
Thu, 02 Aug 2012 07:42:02 -1525 (CD | \d{4} | to try to find the 4 digits
---------------------------------------+---------+-------------------------------
Thu, 02 Aug 2012 07:42:02 -1525 (C | \d{4} | no match
---------------------------------------+---------+-------------------------------
...
---------------------------------------+---------+-------------------------------
Thu, 02 Aug 2012 07:42:02 -1 | \d{4} | no match
---------------------------------------+---------+-------------------------------
Thu, 02 Aug 2012 07:42:02 -1525 | \d{4} | match
---------------------------------------+---------+-------------------------------