比较字符串并提取变量?

时间:2010-11-24 16:15:14

标签: php string

有人能告诉我如何做到这一点。我有3个字符串。

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

我需要做的是检查网址是否符合路线。我试着这样做。

$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 个答案:

答案 0 :(得分:1)

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

未经测试且不确定它如何对不相等的数组长度做出反应,但这可能是您在寻找元素到元素匹配时的看法。然后你几乎可以迭代数组并查找$并使用另一个值来替换它。

修改

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

关闭RegEx,除非你需要在正则表达式中“转义”$,因为这是字符串结尾的标志(因此是\ x24)。 [0-9] +是1+个数的匹配。 ^表示匹配字符串的开头,并且如上所述,$表示匹配结尾。这将确保它始终是一个美元符号,然后是一个数字。

(实际上,netcoder有一个很好的解决方案)

答案 1 :(得分:1)

我在自己的小框架中做了类似的事情。

我的解决方案是转换模板网址:/user/$1/profile/$2

进入能够解析参数的正则表达式:^\/user\/([^/]*)/profile/([^/]*)\/$

然后检查正则表达式是否匹配。

如果需要,您可以查看my controller code

答案 2 :(得分: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
}

答案 3 :(得分:0)

您可以使用相同的号码$n替换(?P<_n>[^/]+)的{​​{1}},然后将其用作named group的模式:

$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/的{​​{1}}也可以使用)。并且命名的子模式允许您使用任意顺序(例如/~jason/也适用)。

如果快速失败,您还可以使用preg_match