1

我有一个要匹配某个模式的 url

/事件/显示/ID/精选

在哪里

  • 匹配 /events/ 之后的所有内容
  • 显示匹配到键
  • id 和 features 是 1 个或多个匹配到一个键

因此我最终得到

Array (
 [method] => display
[param] => Array ([0]=>id,[1]=>featured,[2]=>true /* if there was another path */)
)

到目前为止我有

(?:/events/)/(?P<method>.*?)/(?P<parameter>.*?)([^/].*?)

但它没有按预期工作。

语法有什么问题?

PS 不,我不想使用 parse_url() 或 php 定义的函数,我需要一个正则表达式

4

3 回答 3

2

您可以使用此模式:

<pre><?php
$subject = '/events/display/id1/param1/id2/param2/id3/param3';

$pattern = '~/events/(?<method>[^/]+)|\G(?!\A)/(?<id>[^/]+)/(?<param>[^/]+)~';

preg_match_all($pattern, $subject, $matches, PREG_SET_ORDER);

foreach($matches as $match) {
    if (empty($match['method'])) {
        $keyval[] = array('id'=>$match['id'], 'param'=>$match['param']);
    } else {
        $result['method'] = $match['method'];
    }
}
if (isset($keyval)) $result['param'] = $keyval;
print_r($result);

图案细节:

~
/events/(?<method>[^/]+)   # "events" followed by the method name 
|                          # OR
\G                         # a contiguous match from the precedent
(?!\A)                     # not at the start of the string
/(?<id>[^/]+)              # id
/(?<param>[^/]+)           # param
~
于 2013-07-31T17:43:24.007 回答
2

Why not using a mix of preg_match() and explode()?:

$str = '/events/display/id/featured';
$pattern = '~/events/(?P<method>.*?)/(?P<parameter>.*)~';
preg_match($pattern, $str, $matches);

// explode the params by '/'
$matches['parameter'] = explode('/', $matches['parameter']);
var_dump($matches);

Output:

array(5) {
  [0] =>
  string(27) "/events/display/id/featured"
  'method' =>
  string(7) "display"
  [1] =>
  string(7) "display"
  'parameter' =>
  array(2) {
    [0] =>
    string(2) "id"
    [1] =>
    string(8) "featured"
  }
  [2] =>
  string(11) "id/featured"
}
于 2013-07-31T17:08:39.810 回答
0

在这里,我基本上是preg_match_all()用来重新创建类似于explode(). 然后我将结果重新映射到一个新数组。不幸的是,这不能单独使用 Regex 来完成。

<?php

$url = '/events/display/id/featured/something-else';
if(preg_match('!^/events!',$url)){
    $pattern = '!(?<=/)[^/]+!';
    $m = preg_match_all($pattern,$url,$matches);

    $results = array();

    foreach($matches[0] as $key=>$value){
        if($key==1){
            $results['method']=$value;  
        }   elseif(!empty($key)) {
            $results['param'][]=$value;
        }
    }
}

print_r($results);

?>

输出

Array
(
    [method] => display
    [param] => Array
        (
            [0] => id
            [1] => featured
            [2] => something-else
        )

)
于 2013-07-31T20:00:47.907 回答