2011-11-12 4 views
1

누구나이 문제를 해결할 수 있습니다.경로를 캡처하는 정규식 변수를 만드는 방법

example $uri = '/username/carlos'; => $routes[] = '/username/@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

왜 readymade 라우팅 프레임 워크를 사용하지 않습니까? 그리고 중첩 된 패턴 변환 부분을 먼저 디버그하여 디버깅하지 않아야합니까? – mario

답변

1

을 읽기위한 변수 $ 이름 캡처 문자열로 변환 @name 주로 경로를 정규 표현식으로 변환하여 주어진 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>[^/]+)에 @param를 변환하거나 :

후 표현 [^/]+ 대체로 일치하는 항목이 있으면 나는 그것을 할 것입니다 방법은 , 일치를 $params으로 설정하고 foreach 루프를 종료합니다. 이름을 찾으려면 그냥 사용해야합니다.

echo $param['name']; 
+0

안녕하세요, $ uri = '/list/edit/123.html'에 대한 정규식 방법; $ routes [] = '/list/edit/@id:[0-9]{3}.html'; 결과는 "123.html"이지만 아무런 작업도하지 못합니다. "123"sorry my english! – zetanova

+0

대신 검색하기 위해 basename을 사용할 수 있습니다. http://www.php.net/basename –

관련 문제