2012-11-06 50 views
2

我尝试建立正则表达式验证(的preg_match)一些路径字符串为以下两个规则:检查目录路径范围和“..”向上目录签署

  1. 路径必须由来自给定的范围[a-zA-z0-9-_\///\.]只有符号
  2. 道路不会由一个备份目录序列 “..”

这是一个正确的路径例如:/user/temp

和坏的一个:/../user

UPD: /user/temp.../foo也将是正确的(感谢劳伦斯·贡萨尔维斯

+0

'/ user/foo..bar/baz'认为有效吗? –

+0

是的,..foo/bar,/foo..bar/baz是正确的路径示例,谢谢你的提示! – sharp

+0

更新了我的答案。 – raina77ow

回答

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-9,a-zA-Z,_(下划线),-(连字符),.(点)和两个斜线(/\)。

[-\w.\\/] 

这里注意两件事情:1)连字符应该是第一或在字符类中的最后一个符号(否则就前三的位置可以用一个快捷方式(\w),则需要一个字符类来表示视为用于定义范围的元字符); 2)点和正斜杠都没有被转义(反斜线被转义;尽管如此,它太强大了,不能单独使用,即使在[...]子表达式中也是如此)。

2)现在我们必须确保模式确实覆盖整个字符串。我们用所谓的锚点 - ^开始字符串,$结束。而且,不要忘记我们的字符串可能包含一个或多个允许的符号(用+量词表示)。所以图案变成这样:

^[-\w.\\/]+$ 

3)最后一件事 - 我们必须避免使用../..\(由/\之前 - 与否,如果..[/\\]序列开始的字符串)也是如此。

表达这一规则的最简单的方法是使用所谓的“negative lookahead”测试。它的内(?!...)子表达式编写的,(在这种情况下)记载了下述理念:“确保零个或多个符号该序列后面没有‘砍伐两个点斜杠’序”:

^(?!.*[\\/]\.{2}[\\/])(?!\.{2}[\\/])[-\w.\\/]+$ 

最后一件事实际上是将图案为preg_match功能:当我们使用正则表达式中/符号,我们可以只选择另一组分隔符。在我的示例中,我选择了“#”:

$pattern = '#^(?!.*[\\/]\.{2}[\\/])(?!\.{2}[\\/])[-\w.\\/]+$#'; 

请参阅?这很容易。 )你必须从小事做起,逐步发展。

+0

谢谢,对于优秀的解释) – sharp