Сравнить строки и извлечь переменные? - PullRequest
0 голосов
/ 24 ноября 2010

Может кто-нибудь сказать мне, как я это сделаю.У меня есть 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?

Ответы [ 4 ]

1 голос
/ 24 ноября 2010

Я сделал что-то похожее в моей собственной маленькой структуре.

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

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

Затем я проверяю, соответствует ли регулярное выражение или нет.

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

1 голос
/ 24 ноября 2010

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

$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
}
1 голос
/ 24 ноября 2010
$route_segments = explode('/',$route);
$url_segments = explode('/',$url);
$combined_segments = array_combine($route_segments,$url_segments);

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

РЕДАКТИРОВАТЬ

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

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

(на самом деле, у netcoder есть хорошее решение)

0 голосов
/ 24 ноября 2010

Вы можете заменить любое вхождение $n на именованную группу с тем же номером (?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/ также работает).

А для быстрого сбоя вы можете дополнительно использовать синтаксис атомной группировки (?>…).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...