2011-05-10 121 views
13

我正在做一個日期匹配正則表達式,而這一切都做得較好,我得到這個至今:PHP正則表達式非捕獲不匹配組

"/(?:[0-3])?[0-9]-(?:[0-1])?[0-9]-(?:20)[0-1][0-9]/" 

它(希望)單相匹配或在二十一世紀的兩位數天和幾個月,以及兩位或四位數年份。一些試驗和錯誤已經讓我走到了盡頭。

但是,我已經得到了關於這些結果兩個簡單的問題:

  1. (?:)究竟是什麼簡單的解釋?顯然它是一個不匹配的組。但是...

  2. 什麼是尾隨??例如(?)?

回答

25

[編輯(再)來改善格式和固定介紹]

這是一條評論和答覆。

答案部分......我同意亞歷克斯的早期回答。

  1. (?:),而相比之下,(),是爲了避免在拍攝文字,一般以少回拋出這些引用你想或者提高速度性能。

  2. The?在(?:)之後 - 或者在跟隨* + ?{}之後的任何情況時 - 表示前面的項目可能在合法匹配中找到或可能找不到。例如,/z34?/將匹配Z3和Z34,但它不會匹配Z35或Z等

的註釋部分... ...我做什麼可能被認爲是改善你工作的正則表達式:

(?:^|\s)(0?[1-9]|[1-2][0-9]|30|31)-(0?[1-9]|10|11|12)-((?:20)?[0-9][0-9])(?:\s|$) 

- 首先,它避免了像0-0-2011

東西 - 其次,它避免了像233443-4-201154564事情

- 第三,它包括像1 -1-202 2

- 第四,它包括像1-1-11

- 第五,它避免了之類的東西34-4-11

- 第六,它可以讓你拍攝的日子,月份和年份,以便您可以在代碼中更輕鬆地查看這些內容。例如,將進行進一步檢查的代碼(是第二個捕獲組2,並且是第一個捕獲組29並且這是閏年,或者是第一個捕獲組是< 29),以便查看feb 29日期是否合格。

最後,請注意,您仍然會得到不存在的日期,例如31-6-11。如果你想避免這些,然後嘗試:

(?:^|\s)(?:(?:(0?[1-9]|[1-2][0-9]|30|31)-(0?[13578]|10|12))|(?:(0?[1-9]|[1-2][0-9]|30)-(0?[469]|11))|(?:(0?[1-9]|[1-2][0-9])-(0?2)))-((?:20)?[0-9][0-9])(?:\s|$) 

而且,我認爲會的日期用一個空格的前面和後面(或者乞求/行尾),但您可能想OT調整的是(例如,以允許標點符號)。

一個評論者引用的其他這種資源,你可能會發現有用: http://rubular.com/

+0

第一部分內容非常全面,非常全面和有幫助。我正在使用'/ [0-3]?[0-9] - [0-1]?[0-9] - (?: 20)?[0-1] [0-9] /'然後在組件上運行'checkdate()'來處理假日期。 – Ben 2011-05-10 06:10:51

6
  1. 它是一種非捕獲組。你不能回引用它。通常用於清理反向引用和/或提高性能。
  2. 這意味着上一個捕獲組是可選的。
+0

Groovy。對於未來的用戶來說,這是一個半幫助的進一步解釋:http://www.regular-expressions.info/named.html – Ben 2011-05-10 03:26:31

3

子模式

子模式由圓括號(圓括號)分隔,它可以被嵌套。一種模式爲子模式的標記部分做了兩兩件事:

  1. 它本地化了一套備選方案。例如,貓(aract | erpillar |)的圖案 與單詞「貓」,「白內障」或 「毛毛蟲」中的一個匹配。沒有括號,它會匹配「白內障」, 「erpillar」或空字符串。
  2. 它將子模式設置爲捕獲子模式(如上面定義的 )。當整個模式匹配時,與子模式匹配的主題 字符串的部分將通過 pcre_exec()的ovector參數傳回給調用者。從左向右(從1開始)將開括號計數爲 ,以獲得捕獲子模式的 的編號。

例如,如果字符串「紅王」與圖案匹配((白)(皇后)),則捕獲的子串是「紅色王」,「紅色」和「王「,並且被編號爲1,2和3.

簡單括號實現兩個功能的事實並不總是有幫助的。常常需要一個分組子模式而沒有捕獲需求。如果左括號後面跟着「?:」,則子模式不執行任何捕獲,並且在計算任何後續捕獲子模式的數量時不計算。例如,如果字符串「白皇后」與圖案匹配,則捕獲的子串是「白皇后」和「皇后」,並且被編號爲1和2 。捕獲的子字符串的最大數量是65535.但是,根據libpcre的配置選項,可能無法編譯如此大的模式。

作爲一種方便的簡寫,如果在非捕獲子模式開始時需要任何選項設置,選項字母可能出現在「?」和「:」。因此,這兩種模式

(?i:saturday|sunday) 
(?:(?i)saturday|sunday) 

匹配完全相同的一組字符串。由於可選分支從左到右進行嘗試,直到達到子模式結束時纔會重置選項,因此一個分支中的選項設置會影響後續分支,因此上述模式與「星期日」以及「星期六」匹配。

使用語法(?Ppattern)可以命名子模式。然後,這個子模式將通過正常的數字位置和名稱在匹配數組中進行索引。 PHP 5.2。2引入了兩種替代語法(?模式)和(?'名稱'模式)。

有時需要在正則表達式中具有多個匹配但交替的子組。通常情況下,每個人都會得到自己的反向引用號碼,儘管他們中只有一個可能會匹配。 ?爲了克服這個問題,(|語法允許有重複號考慮對字符串週日匹配以下正則表達式:

(?:(Sat)ur|(Sun))day 

這裏太陽被存儲在反向引用2,而引用1是空的匹配產生坐在後向引用。 1,而逆向引用2不存在變着花樣使用(|修復了這個問題:?

(?|(Sat)ur|(Sun))day 

地使用這種模式,Sun和週六都將存儲在反向引用1.

參考:http://php.net/manual/en/regexp.reference.subpatterns.php