我想匹配包含可选段的网址格式。
我有这样的网址:
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
谢谢!
答案 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指出的那样(谢谢)我的流行模式与你最后一个示例字符串不匹配,哎呀