2010-03-25 184 views
1

以下面的正則表達式匹配爲例。preg_match匹配可選字符串,但不匹配所有字符串

preg_match('!^publisher/([A-Za-z0-9\-\_]+)/([0-9]+)/([0-9]{4})-(january|february|march|april|may|june|july|august|september|october|november|december):([0-9]{1,2})-([0-9]{1,2})/([A-Za-z0-9\-\_]+)/([0-9]+)(/page-[0-9]+)?$!', 'publisher/news/1/2010-march:03-23/test_title/1/page-1', $matches); 
print_r($matches); 

它產生以下:

Array 
(
    [0] => publisher/news/1/2010-march:03-23/test_title/1/page-1 
    [1] => news 
    [2] => 1 
    [3] => 2010 
    [4] => march 
    [5] => 03 
    [6] => 23 
    [7] => test_title 
    [8] => 1 
    [9] => /page-1 
) 

然而,由於最後一場比賽是可選的,也可以與符合以下「發行人/新聞/ 1/2010年三月工作:03-23/test_title/1" 。我的問題是,如果它存在,我希望能夠匹配(/ page- [0-9] +),但只匹配頁碼,以便「publisher/news/1/2010-march:03-23/test_title/1 /頁-1" 將匹配像這樣:

Array 
(
    [0] => publisher/news/1/2010-march:03-23/test_title/1/page-1 
    [1] => news 
    [2] => 1 
    [3] => 2010 
    [4] => march 
    [5] => 03 
    [6] => 23 
    [7] => test_title 
    [8] => 1 
    [9] => 1 
) 

我試過以下的正則表達式

'!^publisher/([A-Za-z0-9\-\_]+)/([0-9]+)/([0-9]{4})-(january|february|march|april|may|june|july|august|september|october|november|december):([0-9]{1,2})-([0-9]{1,2})/([A-Za-z0-9\-\_]+)/([0-9]+)/?p?a?g?e?-?([0-9]+)?$!' 

這工作,但它也將匹配「發行人/新聞/ 1/2010年三月:03-23/test_title/1/1" 。我不知道要進行比賽但是沒有回到比賽中?在一個正則表達式中可能嗎?

回答

2

絕對不匹配publisher/news/1/2010-march:03-23/test_title/1/whatever

!^publisher/([A-Za-z0-9\-\_]+)/([0-9]+)/([0-9]{4})-(january|february|march|april|may|june|july|august|september|october|november|december):([0-9]{1,2})-([0-9]{1,2})/([A-Za-z0-9\-\_]+)/([0-9]+)(?:/page-([0-9]+))?$! 

要仍然匹配publisher/news/1/2010-march:03-23/test_title/1/whatever卻忽略了/whatever

!^publisher/([A-Za-z0-9\-\_]+)/([0-9]+)/([0-9]{4})-(january|february|march|april|may|june|july|august|september|october|november|december):([0-9]{1,2})-([0-9]{1,2})/([A-Za-z0-9\-\_]+)/([0-9]+)(?:(?:/page-([0-9]+))|/.*)?$! 
+0

這就是票。謝謝。是否:只有存在時才表示匹配? – buggedcom

+0

?:使括號「不捕獲」。所以,在你的例子中的數組中,0是模式匹配的整個字符串。 1-9是「捕獲」,你包裹在()中的所有東西都在你的模式中。 (?:)將「/ page」和「[0-9] +」分組在一起,但不會「捕獲」它們。 –

+0

Ah k歡呼聲。對不起,我不能投票,我還沒有我的+15代表... – buggedcom

0

也許這樣的:

'!^publisher/([A-Za-z0-9\-\_]+)/([0-9]+)/([0-9]{4})-(january|february|march|april|may|june|july|august|september|october|november|december):([0-9]{1,2})-([0-9]{1,2})/([A-Za-z0-9\-\_]+)/([0-9]+)(/page-([0-9]+))?$!' 
+0

不,因爲那樣會匹配「/ page-1」和「1」。我只希望它匹配「1」。它被用於一個自動化的url路由系統,正則表達式匹配正在被佔位符代替,所以任何返回的匹配都必須匹配佔位符的數量。 – buggedcom

0

這是正則表達式,你是什麼尋找:

^publisher/([A-Za-z0-9\-\_]+)/([0-9]+)/([0-9]{4})-(january|february|march|april|may|june|july|august|september|october|november|december):([0-9]{1,2})-([0-9]{1,2})/([A-Za-z0-9\-\_]+)/([0-9]+)/(?:page-(\d+))? 

你可以在rexexbuddy中測試它。如果沒有設置「page-1」,則會將var 9留空,否則將設置它。

+0

謝謝,但是馬特也打敗了你。 (\ d +)超過([0-9] +)真的有什麼優勢嗎? – buggedcom

+0

我不確定在性能方面是否有真正的差異。 \ d是用於數字,而[0-9]只是一個範圍,就像您可以使用[a-z]一樣。 – RJD22