检查符号范围的目录路径和“..”上的目录符号

时间:2012-11-06 22:21:26

标签: regex path preg-match

我尝试构建RegExp以验证(preg_match)以下两条规则的某些路径字符串:

  1. 路径必须仅包含来自给定范围[a-zA-z0-9-_\///\.]
  2. 的符号
  3. 路径不包含上行目录序列“..”
  4. 这是一个正确的路径示例:/user/temp

    和坏的:/../user

    UPD: /user/temp.../foo也是正确的(感谢 Laurence Gonsalves

1 个答案:

答案 0 :(得分:2)

考虑一下:

$right_path = '/user/temp';
$wrong_path = '/../user';
$almost_wrong_path = 'foo/abc../bar';
$almost_right_path = 'foo/../bar';

$pattern = '#^(?!.*[\\/]\.{2}[\\/])(?!\.{2}[\\/])[-\w.\\/]+$#';
var_dump(preg_match($pattern, $right_path)); // 1
var_dump(preg_match($pattern, $wrong_path)); // 0
var_dump(preg_match($pattern, $almost_wrong_path)); // 1
var_dump(preg_match($pattern, $almost_right_path)); // 0

我实际上分三步构建了这个模式:

1)给出的第一条规则说只有字符串中允许的符号为0-9a-zA-Z_(下划线),-(连字符),{{ 1}}(点)和两个斜杠(./)。前三个位置可以用快捷方式表示(\),其他位置需要一个字符类:

\w

注意这里有两件事:1)连字符应该是字符类中的第一个或最后一个符号(否则它被视为用于定义范围的元字符); 2)点和正斜杠都没有被转义(但是反斜杠被转义;它太强大了,即使在[-\w.\\/] 子表达式内也不能单独存在)。

2)现在我们必须确保模式确实覆盖了整个字符串。我们使用所谓的锚点 - [...]表示字符串的开头,^作为结尾。并且,不要忘记我们的字符串可能包含一个或多个允许的符号(用$量词表示)。因此模式变为:

+

3)最后一件事 - 我们必须阻止使用^[-\w.\\/]+$ ../(前面有..\/ - 否则,如果\序列也开始了字符串。

表达此规则的最简单方法是使用所谓的“negative lookahead”测试。它写在(?!...)子表达式中,并且(在本例中)描述了以下思想:'确保零个或多个符号的序列后面没有“斜线 - 两个点 - 斜线”序列':

..[/\\]

最后一件事实际上是将模式放入^(?!.*[\\/]\.{2}[\\/])(?!\.{2}[\\/])[-\w.\\/]+$ 函数中:因为我们在正则表达式中使用preg_match符号,我们可以选择另一组分隔符。在我的例子中,我选择了'#':

/

请参阅?这真的很容易。你只需从小事做起,逐步发展它们。