如何从已知的URL格式解析令牌?

时间:2013-12-25 21:15:39

标签: php arrays regex string

我在 PHP 中有一个字符串,它反映了为网站选择的 URL 路由格式 - 它根据方案中传递的索引/指令动态构建内容。例如,典型的请求格式可能如下所示:

$str = '/something-new/:id/goto/:new_id/full/page/:num/';

我想要提取的数据是每个索引的实体名称,它们总是以冒号:开头。我不确定最好的方法 - “拆分”字符串似乎很麻烦。将这些结果数据导入数组的最简单方法是什么?

$arr = [
    [0] => 'id', 
    [1] => 'new_id', 
    [2] => 'num'
];

4 个答案:

答案 0 :(得分:5)

preg_match_all('~:(.*?)/~', $str, $matches);
print_r($matches[1]);

: demo

答案 1 :(得分:2)

我不确定我是否理解正确但是:

$str = '/something-new/:id/goto/:new_id/full/page/:num/';
$arr = explode('/', $str);
$arr = array_filter($arr, function($element) {
    return strpos($element, ':') === 0;
 });
$arr = array_values($arr);
$arr = array_map(function($element) {
    return substr($element, 1);
}, $arr);

结果:

$arr = array([0] => 'id', [1] => 'new_id', [2] => 'num');

答案 2 :(得分:2)

只需使用preg_match_all仅匹配:之后的字母字符:

$str = '/something-new/:id/goto/:new_id/full/page/:num/';
preg_match_all("/:[a-zA-Z_]*/", $str, $matches);
echo '<pre>';
print_r($matches[0]);
echo '</pre>';

输出结果为:

Array
(
    [0] => :id
    [1] => :new_id
    [2] => :num
)

然后只需翻阅$matches[0]即可获得最终数组:

$str = '/something-new/:id/goto/:new_id/full/page/:num/';
preg_match_all("/:[a-zA-Z_]*/", $str, $matches);
if (!empty($matches[0])) {
  $arr = array();
  foreach ($matches[0] as $match_key => $match_value) {
    $arr[] = preg_replace('/:/', '', $match_value);
  }
}
echo '<pre>';
print_r($arr);
echo '</pre>';

所以$arr的值现在是这样的:

Array
(
    [0] => id
    [1] => new_id
    [2] => num
)

答案 3 :(得分:1)

我使用带有命名模式的正则表达式,例如:

~^/something-new/(?<id>[^/]+)/goto/(?<new_id>[^/]+)/full/page/(?<num>.*)$~

preg_match

示例

<?php
  $url = '/something-new/123/goto/321/full/page/1337';

  if (preg_match('~^/something-new/(?<id>[^/]+)/goto/(?<new_id>[^/]+)/full/page/(?<num>.*)$~', $url, $match)) {
    var_dump( $match['id'] , $match['new_id'] , $match['num'] );
  }
?>

<强>输出

string(3) "123"
string(3) "321"
string(4) "1337"

DEMO

修改

根据我的评论,确保您知道如果网址中存在实际冒号,则会将其称为:123:321等。

  

我不知道,但我认为:foo是指SQL语言准备语句中的命名参数,并不包含在实际的URL中。不过,这只是猜测。