2011-11-12 66 views
1

任何人都可以幫助我解決這個問題。如何使正則表達式變量捕獲路由

example $uri = '/username/carlos'; => $routes[] = '/username/@name'; 

@name變量$名稱捕獲字符串轉換「卡洛斯」

$routes[] = '/list/edit/@id:[0-9]{3}'; 

$routes[] = '/username/@name'; 

$routes[] = '/archive/*'; 

$routes[] = '/'; 


$uri = '/username/carlos'; 

foreach ($routes as $pattern) 
{ 
    if (preg_match('#^' . preg_replace('#(?:{{)[email protected](\w+\b)(?:}})?#i', '(?P<\1>[\w\-\.!~\*\'"(),\s]+)', 
          str_replace('\*', '(.*)', preg_quote($pattern, '/'))) . '\/?$#i', $uri, $matchs)) 
    { 

     //how to make regex for this to work : 


     echo $name; // carlos =>$uri = '/username/carlos'; or matt => $uri = '/username/matt'; 

    } 
} 

感謝閱讀

+0

爲什麼不使用現成的路由框架?你不應該首先分解嵌套模式轉換部分來調試它嗎? – mario

回答

1

還有很多更你需要做的就是這個工作的工作,主要是將路由轉換爲正則表達式,然後可以在給定的URI上使用。我會做的方式是如下

$routes = $params = array(); 

$routes[] = '/list/edit/@id:[0-9]{3}'; 
$routes[] = '/username/@name'; 
$routes[] = '/archive/*'; 
$routes[] = '/'; 

$uri = '/username/carlos'; 

foreach($routes as $pattern) { 
    // Convert all characters into safe characters 
    $pattern = preg_quote($pattern, '~'); 

    // Convert * into .*? 
    $pattern = preg_replace('/(?<!\\\\)\\\\\*/', '.*?', $pattern); 

    #echo '<pre>'.print_r($pattern, true).'</pre>'; 
    // Convert any @name:expression into their expressions for capture 
    $pattern = preg_replace_callback('%@([a-zA-Z]+)(\\\\:([^/]+))?%', 'regex_callback', $pattern); 

    $pattern = '~^' . $pattern . '$~'; 

    if(preg_match($pattern, $uri, $matches)) { 
     $params = $matches; 
     break; 
    } 
} 

echo '<pre>'.print_r($params, true).'</pre>'; 

function regex_callback($data) { 
    #echo '<pre>'.print_r($data, true).'</pre>'; 
    $pattern = '[^/]+'; 
    if(!empty($data[3])) { 
     $pattern = stripslashes($data[3]); 
    } 
    return '(?P<' . $data[1] . '>' . $pattern . ')'; 
} 

它轉換成*.*?,然後@參數轉換爲(?P<param>[^/]+),或爲:

後的表達代替[^/]+如果發現匹配,它將匹配項設置爲$params,並退出foreach循環。要找到名稱,您只需要使用

echo $param['name']; 
+0

嗨,如何正則表達式$ uri ='/list/edit/123.html'; with $ routes [] ='/list/edit/@id:[0-9]{3}.html';結果是「123.html」,但沒有工作單變量「123」對不起我的英語! – zetanova

+0

您可以使用basename來檢索。 http://www.php.net/basename –