从正则表达式中获取字符串?

时间:2011-03-15 21:10:11

标签: php regex

有没有办法与正则表达式相反?简单来说就是路由引擎... 它设置得很好,但我正在编写一个函数来构建链接的URL。这是一个routes.php文件:

 class Router {

     /*
      * @var urls Contains info about routes
      * @format '{^REGEX(?<url_paramaters>$}' => array('ControllerClassName', 'ActionName', array/string('method(s)'))
      */

     var $urls = array(
        array('{^$}' => array('PagesController', 'index')),
        array('{^contact$}' => array('PagesController', 'contact', 'get')),
        array('{^about$}' => array('PagesController', 'about', 'get')),
        array('{^users/(?<user_id>\d+)$}' => array('UsersController', 'show')),
     );
  }

右。所以一切正常。调度程序将URL与正则表达式匹配,然后使用正则表达式之后的数组调度它。 这是我的URL构建器功能...目前:

function build(array $resource = null) {    
    $routes = new Router;
    $controller = ucwords((isset($resource['controller'])) ? $resource['controller'] : $GLOBALS['controller']) . "Controller";
    $action = (isset($resource['action'])) ? $resource['action'] : 'index';
    // Loop through the routes to find the right Regex using the callback
    foreach($routes->urls as $route) {
        $regex = array_keys($route);
        $regex = $regex[0]; //Eg/ ^users/(?<user_id>\d+)$
        $callback = $route[$regex];
        // ?? Something in here.
    }
}

想象一下,$ resource可能包含“user_id”=&gt;之类的内容123.如何通过正则表达式将捕获组设置为正确的值? 我希望我措辞得足够好! 提前致谢, 布拉德

3 个答案:

答案 0 :(得分:0)

也许这可以帮助

preg_match('@/users/(?P<userId>\d+)/@Uis', $_SERVER['REQUEST_URL'], $matches);
// url: /users/1/
// $matches['userId'] = 1

答案 1 :(得分:0)

你应该使用普通的字符串连接并准备一个普通的php地图(而不是试图将regexpressions转换成一个)。例如:

// if $resource contains the capture groups
$keys = implode(",", array_keys($r = $resource));

// you would need an if-tree or switch to avoid notices here
$map = array(
    "user_id" => "users/$r[user_id]",
    "PagesController,contact,get" => "contact",
    "" => "",
}
return $map[$keys];

您会发现正则表达式URL映射不能单独与捕获组一起使用。您需要“联系”和“关于”页面的其他线索。我在这里使用路由参数作为示例。但是,您可以在原始正则表达式中创建一个未使用的捕获组:

array('{^(?<contact>contact)$}' => ...

答案 2 :(得分:0)

想想我已经明白了。这可能是一个非常糟糕的解决方案,但无论如何它在这里。 PS。如果可以,请优化它! TA

function build(array $resource = null) {

  $routes = new Router;
  $controller = ucwords((isset($resource['controller'])) ? $resource['controller'] : $GLOBALS['controller']) . "Controller";
  $action = isset($resource['action']) ? $resource['action'] : 'index';
  // Loop through the routes to find the right Regex using the callback
  foreach($routes->urls as $route) {
    $regex = array_keys($route);
    $regex = $regex[0]; // ^users/(?<user_id>\d+)$
    $callback = $route[$regex];
    if($controller == $callback[0] && $action == $callback[1]) {
    $url = substr($regex, 2, -2);
    foreach($resource as $key => $value) {
      $url = preg_replace("/\??\(\?<".$key.">[^\)]+\)\??/", $value, $url);
      $url = preg_replace("/\)?\(?\??/", "", $url);
    }
    break;
    }
  }

  return "/".$url."/";

}