2010-11-24 3 views
0

Может ли кто-нибудь сказать мне, как я это сделаю. У меня 3 строки.Сравнить строки и извлекать переменные?

$route = '/user/$1/profile/$2'; 
$path = '/user/profile/$1/$2'; 
$url = '/user/jason/profile/friends'; 

Что мне нужно сделать, это проверить, соответствует ли URL-адрес маршруту. Я пытаюсь сделать это следующим образом.

$route_segments = explode('/', $route); 
$url_segments = explode('/', $url); 

$count = count($url_segments); 
for($i=0; $i < $count; $i++) { 
    if ($route_segments[$i] != $url_segments[$i] && ! preg_match('/\$[0-9]/', $route_segments[$i])) { 
    return false; 
    } 
} 

Я предполагаю, что регулярное выражение работает, это первое, что я когда-либо писал. : D

Здесь я застреваю. Как сравнить следующие строки:

$route = '/user/$1/profile/$2'; 
$url = '/user/jason/profile/friends'; 

Так что я в конечном итоге с:

array (
    '$1' => 'jason', 
    '$2' => 'friends' 
); 

Я полагаю, что с этим массивом я мог бы тогда str_replace эти значения в переменной $ PATH?

ответ

1
$route_segments = explode('/',$route); 
$url_segments = explode('/',$url); 
$combined_segments = array_combine($route_segments,$url_segments); 

Непроверенные и не знает, как он реагирует с разной длиной массива, но это, вероятно, что вы ищете в отношении к спичке элемента к элементу. Затем вы можете довольно много итерации массива и искать $ и использовать другое значение для его замены.

EDIT

/^\x24[0-9]+$/ 

Закрыть на RegEx за исключением вам нужно "Escape" в $ в регулярном выражении, потому что это флаг для конца строки (таким образом, \ x24). [0-9] + соответствует 1 + числу. Элемент^означает совпадение с началом строки, и, как объяснено, соответствие $ означает конец. Это гарантирует, что это всегда знак доллара, а затем номер.

(на самом деле, netcoder имеет красивое решение)

+0

Мне нравится это решение, его простое и точное. Спасибо за подсказку в регулярном выражении. – JasonS 2010-11-24 16:40:16

1

я сделал что-то подобное в небольших рамках моего собственные.

Мое решение было преобразовать шаблон URL: /user/$1/profile/$2

в регулярное выражение, способный параметров разборе: ^\/user\/([^/]*)/profile/([^/]*)\/$

я затем проверить, если регулярное выражение спичек или нет.

Вы можете взглянуть на my controller code, если вам нужно.

+0

Главной точкой продажи моего небольшого приложения является простота. Я чувствую, что это противоречит этому принципу. Это приятное решение, хотя спасибо. – JasonS 2010-11-24 16:37:04

1

Вы можете сделать это:

$route = '/user/$1/profile/$2'; 
$path = '/user/profile/$1/$2'; 
$url = '/user/jason/profile/friends'; 

$regex_route = '#'.preg_replace('/\$[0-9]+/', '([^/]*)', $route).'#'; 
if (preg_match($regex_route, $url, $matches)) { 
    $real_path = $path; 
    for ($i=1; $i<count($matches); $i++) { 
     $real_path = str_replace('$'.$i, $matches[$i], $real_path); 
    } 
    echo $real_path; // outputs /user/profile/jason/friends 
} else { 
    // route does not match 
} 
0

Вы можете заменить любое вхождение $n по named group с тем же номером (?P<_n>[^/]+), а затем использовать его как шаблон для preg_match:

$route = '/user/$1/profile/$2'; 
$path = '/user/profile/$1/$2'; 
$url = '/user/jason/profile/friends'; 

$pattern = '~^' . preg_replace('/\\\\\$([1-9]\d*)/', '(?P<_$1>[^/]+)', preg_quote($route, '~')) . '$~'; 
if (preg_match($pattern, $url, $match)) { 
    var_dump($match); 
} 

Печатается в этот случай:

array(5) { 
    [0]=> 
    string(28) "/user/jason/profile/friends" 
    ["_1"]=> 
    string(5) "jason" 
    [1]=> 
    string(5) "jason" 
    ["_2"]=> 
    string(7) "friends" 
    [2]=> 
    string(7) "friends" 
} 

Использование регулярного выражения позволяет использовать подстановочные знаки в любой позиции в пути, а не как отдельный сегмент пути (например,/~$1/ для /~jason/ будет работать тоже). И названные подшаблоны позволяют использовать произвольный порядок (например, /$2/$1/).

И для быстрого отказа вы можете дополнительно использовать atomic grouping syntax (?>…).

Смежные вопросы