preg_match匹配可选字符串,但不匹配所有字符串

问题描述:

以下面的正则表达式匹配为例。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" 。我不知道要进行比赛但是没有回到比赛中?在一个正则表达式中可能吗?

绝对不匹配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

也许这样的:

'!^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

这是正则表达式,你是什么寻找:

^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