PHP preg_match url的一部分

时间:2010-11-18 05:33:51

标签: php regex

我正在尝试用PHP创建一个url路由器,就像django一样。

问题是,我不太清楚php正则表达式。

我希望能够像这样匹配网址:

/post/5/
/article/slug-goes-here/

我有一系列正则表达式:

$urls = array(      
  "(^[/]$)" => "home.index",     
  "/post/(?P<post_id>\d+)/" => "home.post",    
);

数组中的第一个正则表达式用于匹配/的主页,但我无法让第二个正则表达式工作。

以下是我用来匹配它们的代码:

foreach($urls as $regex => $mapper) {
    if (preg_match($regex, $uri, $matches)) {
    ...
    }
}

我还应该注意,在上面的示例中,我尝试匹配网址中的post_id/post/5/,以便我可以将5传递给我的方法。< / p>

3 个答案:

答案 0 :(得分:3)

您必须分隔正则表达式。分隔允许您提供“选项”(例如“i”用于不区分大小写的匹配)作为模式的一部分:

,/post/(?P<post_id>\d+)/,

在这里,我用逗号分隔了正则表达式。

正如你发布的那样,你的正则表达式用/分隔,这意味着它在第二个/作为'选项'之后处理所有内容,并且只尝试匹配“发布”部分。

根据您当前的正则表达式,您尝试匹配的示例看起来不像您实际上的那样。

如果你正在使用匹配类似的正则表达式

/post/P1234/

然后,以下内容:

preg_match(',/post/(P\d+)/,', '/post/P1234/', $matches);
print_r($matches);

将导致:

Array
(
    [0] => /post/P1234/
    [1] => P1234
)

希望能为你清除它:)

修改

根据您对OP的评论,您只是尝试匹配网址的/ post /部分后面的数字,因此这个稍微简化的版本:

preg_match(',/post/(\d+)/,', '/post/1234/', $matches);
print_r($matches);

将导致:

Array
(
    [0] => /post/1234/
    [1] => 1234
)

答案 1 :(得分:1)

如果您的第二个RegExp旨在匹配/ article / slug-goes-here /等网址,则正确的正则表达式为

#\/article\/[\w-]+\/#

应该这样做!我不太确定必须逃避/,所以你可以尝试不逃避它们。标记Im guessing是从.NET示例中提取的,因为该框架使用此类标记来命名匹配组。

我希望我可以帮忙!

答案 2 :(得分:1)

  

php 5.2.2:命名子模式现在接受语法(?<name>)和   (?'name')以及(?P<name>)。以前的版本只接受   (?P<name>)

http://php.net/manual/fr/function.preg-match.php