需要一个正则表达式来创建友好的URL

时间:2011-12-14 14:54:47

标签: php regex

很久以前我问了几乎同样的事情,但现在我需要更多的东西。我需要相同的正则表达式代码来处理所有请求(如果可能的话)

所以,让我说我有以下内容:

$friendly = ''; to output /
$friendly = '/////'; to output /
$friendly = '///text//'; to output /text/
$friendly = '/text/?var=text'; to output /text/
$friendly = '/text/?var=text/'; to output /text/var-text/
$friendly = '/?text!@#$%^&*(()_+|/#anchor'; to output /text/
$friendly = '/!@#$%^&*(()_+|text/!@#$%^&*(()_+|text/'; to output /text/text/

希望有意义!

1 个答案:

答案 0 :(得分:4)

似乎preg_replace()parse_url()rtrim()的组合会对此有所帮助。

$values = array(
    ''                                        => '/'
  , '/////'                                   => '/'
  , '///text//'                               => '/text/'
  , '/text/?var=text'                         => '/text/'
  , '/text/?var=text/'                        => '/text/var-text/'
  , '/?text!@#$%^&*(()_+|/#anchor'            => '/text/'
  , '/!@#$%^&*(()_+|text/!@#$%^&*(()_+|text/' => '/text/text/'
);

foreach( $values as $raw => $expected )
{
  /* Remove '#'s that don't appear to be document fragments and anything
   *  else that's not a letter or one of '?' or '='.
   */
  $url = preg_replace(array('|(?<!/)#|', '|[^?=#a-z/]+|i'), '', $raw);

  /* Pull out the path and query strings from the resulting value. */
  $path  = parse_url($url, PHP_URL_PATH);
  $query = parse_url($url, PHP_URL_QUERY);

  /* Ensure the path ends with '/'. */
  $friendly = rtrim($path, '/') . '/';

  /* If the query string ends with '/', append it to the path. */
  if( substr($query, -1) == '/' )
  {
    /* Replace '=' with '-'. */
    $friendly .= str_replace('=', '-', $query);
  }

  /* Clean up repeated slashes. */
  $friendly = preg_replace('|/{2,}|', '/', $friendly);

  /* Check our work. */
  printf(
    'Raw: %-42s - Friendly: %-18s (Expected: %-18s) - %-4s'
      , "'$raw'"
      , "'$friendly'"
      , "'$expected'"
      , ($friendly == $expected) ? 'OK' : 'FAIL'
  );
  echo PHP_EOL;
}

以上代码输出:

Raw: ''                                         - Friendly: '/'                (Expected: '/'               ) - OK  
Raw: '/////'                                    - Friendly: '/'                (Expected: '/'               ) - OK  
Raw: '///text//'                                - Friendly: '/text/'           (Expected: '/text/'          ) - OK  
Raw: '/text/?var=text'                          - Friendly: '/text/'           (Expected: '/text/'          ) - OK  
Raw: '/text/?var=text/'                         - Friendly: '/text/var-text/'  (Expected: '/text/var-text/' ) - OK  
Raw: '/?text!@#$%^&*(()_+|/#anchor'             - Friendly: '/text/'           (Expected: '/text/'          ) - OK  
Raw: '/!@#$%^&*(()_+|text/!@#$%^&*(()_+|text/'  - Friendly: '/text/text/'      (Expected: '/text/text/'     ) - OK  

请注意,此代码会根据您提供的示例传递,但可能无法正确捕获您尝试完成的操作的意图。我已经对代码进行了评论,以解释它的作用,以便您可以在必要时进行调整。

供您参考: