为什么我的代码出现“意外的正则表达式”错误?

时间:2008-12-17 16:05:41

标签: php regex

目标是将当前工作目录拆分为/clients/并查看用户是否在

[something]/clients/[their username]/[something]

例如,目标是输入:

cwd = "/volumes/raid0/www/clients/mikey/test_folder/"
$session->username = "mikey"

返回
$authorized = true

我希望这能识别UNIX和Windows路径,因此它应该寻找“/”或“\”。假设文件名不包含这些字符。

此外,isAdmin()位应该允许管理员访问所有目录。

现在,PHP说:

  

警告:意外的正则表达式错误(8)   C:\ apache的\ htdocs中\用户\ MIKEY \的index.php   在第69行

这是现在的代码。 (第69行在评论中注明。)

if($session->isAdmin())
{
    $authorized = true;
} 
else 
{
  // split cwd at the first instance of /clients/
  $dir = spliti('%(\/|\\)clients(\/|\\)%',getcwd(),2); //this is line 69
  if(count($dir) == 2) // if /clients/ was in cwd
  {
    // check if the second piece of cwd starts with the username.
    $authorized = (preg_match('/^'.$session->username.'//*.$/', $dir[1]));
  } 
  else 
    $authorized = false;
}

8 个答案:

答案 0 :(得分:6)

这里不需要使用正则表达式,而是在另一个字符串中查找字符串。所以这就像是:

$isAuthorized = strpos(str_replace('\\', '/', getcwd()), "/clients/$username/") !== FALSE;

答案 1 :(得分:2)

这种无复杂的正则表达式变体是:

  • 将字符串拆分为"/""\"
  • 在结果数组中搜索"clients"
  • 如果找到,检查下一个位置的元素是否等于用户名

在PHP中(未经测试):

function isAuthorized($session)
{
  $authorized = $session->isAdmin();

  if(!$authorized)
  {
    $parts = split("[/\\\\]", $path);

    // find "clients", compare the following bit to the $session->username
    $clients_pos = array_search("clients", $parts);
    if ($clients_pos && count($parts) >= $clients_pos) 
      $authorized = ($parts[$clients_pos + 1] == $session->username);
    else
      $authorized = false;
  }
  return $authorized;
}

答案 2 :(得分:1)

这样的事情可能会让你开始:

<?php
$regex = '%(.+)(/|\\\\)clients(/|\\\\)(.+)(/|\\\\)(.+)(/|\\\\)%';

preg_match($regex, "/volumes/raid0/www/clients/mikey/test_folder/", &$matches);
var_dump($matches);
?>

输出:

 array(8) {
  [0]=>
  string(45) "/volumes/raid0/www/clients/mikey/test_folder/"
  [1]=>
  string(18) "/volumes/raid0/www"
  [2]=>
  string(1) "/"
  [3]=>
  string(1) "/"
  [4]=>
  string(5) "mikey"
  [5]=>
  string(1) "/"
  [6]=>
  string(11) "test_folder"
  [7]=>
  string(1) "/"
}

应该允许你写这段代码更短。请记住,你必须双重逃脱。我知道这很难看。

答案 3 :(得分:0)

你的正则表达式是否也尝试在路径中考虑反斜杠?这可能没有必要。然后你可以拆分:

'%/clients/%'

(因为你使用%作为正则表达式分隔符,所以你不需要转义常规斜杠。)

答案 4 :(得分:0)

此代码尚未经过测试,标准免责声明适用:

if($session->isAdmin()) {
   $authorized = true;
} else {
   // split cwd at the first instance of /clients/
   $dir = preg_split('/(\/|\\)clients(\\|\/)/i', getcwd());
   if(count($dir) == 2) { // if /clients/ was in cwd
      // check if the second piece of cwd starts with the username.
      $dir = preg_split('/\/|\\/', $dir[1]);
      $authorized = ($dir[0] == $session->username);
   } else {
      $authorized = false;
   }
}

答案 5 :(得分:0)

这修复了我的PHP警告:

if($session->isAdmin())
{
    $authorized = true;
} else {
    // split cwd at the first instance of /clients/
    $dir = spliti('%(/|\\\\)clients(/|\\\\)%',getcwd(),2);
    if(count($dir) == 2) // if /clients/ was in cwd
        {
            // check if the second piece of cwd starts with the username.
            $authorized = (preg_match('%^'.$session->username.'*(/|\\\\)*.$%', $dir[1]));
    } else $authorized = false;
}

问题是,spliti()没有拆分我的cwd()返回...我正在测试的cwd()返回是:

  

C:\阿帕奇\ htdocs中\客户\ MIKEY

我希望能够使用“/”或“\”这种强制我使用正则表达式(对我的知识。)

Ruben的解决方案不太优雅(它似乎限制了允许的目录深度),但如果我无法解决这个问题,可能会有效。

我将继续罢工,看看我是否能理清正在发生的事情(此时我的spliti()正则表达式似乎都存在问题。)

输入/反馈总是受到赞赏,即使它不是问题的完整解决方案(甚至是相关的。如果我的代码很糟糕,请告诉我。)

谢谢! - 将(OP)

答案 6 :(得分:0)

好的,这已经解决了。我需要用preg_split()...

替换split()

答案 7 :(得分:0)

我会检查当前使用的DIRECTORY_SEPARATOR,然后对其进行简单的strpos检查:

$cwd = getcwd();
if (DIRECTORY_SEPARATOR != '/') {
    $cwd = str_replace(DIRECTORY_SEPARATOR, '/', $cwd);
}
$authorized = (strpos($cwd, '/clients/'.$session->username.'/') !== false);