正则表达式,按特定顺序匹配网址段?

时间:2012-02-18 18:18:12

标签: php regex

我想匹配包含可选段的网址格式。

我有这样的网址:

subdomain.domain.com/page/pageurl/pagename/123/
subdomain.domain.com/page/pageurl/pagename/
subdomain.domain.com/page/pageurl/
subdomain.domain.com/page/

现在我有一个匹配所有这些情况的正则表达式:

^([a-z]+)\.domain\.com\/page(\/[a-z]+)?(\/[a-z]+)?(\/[0-9]+)?\/?$

但如果你转到这个网址,这个正则表达式会失败:

subdomain.domain.com/page/123/

它也匹配这个网址,我不希望发生这种情况,因为第一段应该是[a-z] +而没有别的。现在我明白为什么会发生这种情况,但是我无法找出正确的正则表达式来满足我的需求。 我需要一个匹配这些URL的正则表达式,但是按顺序排列,所以如果第一页后一段是数字,那么它应该不匹配......

我该怎么做?我现在疯了:S

Rubural示例:LINK

谢谢!

2 个答案:

答案 0 :(得分:4)

我认为你需要的是一个后视

^([a-z]+)\.domain\.com\/page(\/[a-z]+)?(\/[a-z]+)?((?<!\/page)\/[0-9]+)?\/?$

(?<!\/page)应该做的是断言'/ page'不会紧接在数字之前。

修改

我测试了这样:

$re = '/^([a-z]+)\.domain\.com\/page(\/[a-z]+)?(\/[a-z]+)?((?<!\/page)\/[0-9]+)?\/?$/';
foreach(array(
        'subdomain.domain.com/page/pageurl/pagename/123/',
        'subdomain.domain.com/page/pageurl/pagename/',
        'subdomain.domain.com/page/pageurl/',
        'subdomain.domain.com/page/',
        'subdomain.domain.com/page/123/',
        ) as $url
) {
    $matches = array();
    preg_match($re,$url,$matches);
    var_dump($matches);
}

并获得前四名的比赛,而不是最后一名。

答案 1 :(得分:3)

我们可以强制要求第一个'段'的捕获组,并且所有段都是可选的,如下所示: ^([a-z]+)\.domain\.com\/page(?:(\/[a-z]+)(\/[a-z]+)?(\/[0-9]+)?)?\/?$

可能有用的另一件事是允许任何有效的子域,模式看起来像这样:

^([\w.-]+)+\.domain\.com\/page(?:(\/[a-z]+)(\/[a-z]+)?(\/[0-9]+)?)?\/?$

编辑:固定模式,正如Umbrella指出的那样(谢谢)我的流行模式与你最后一个示例字符串不匹配,哎呀