我尝试构建RegExp以验证(preg_match)以下两条规则的某些路径字符串:
[a-zA-z0-9-_\///\.]
这是一个正确的路径示例:/user/temp
和坏的:/../user
UPD:
/user/temp.../foo
也是正确的(感谢 Laurence Gonsalves )
答案 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-9
,a-zA-Z
,_
(下划线),-
(连字符),{{ 1}}(点)和两个斜杠(.
和/
)。前三个位置可以用快捷方式表示(\
),其他位置需要一个字符类:
\w
注意这里有两件事:1)连字符应该是字符类中的第一个或最后一个符号(否则它被视为用于定义范围的元字符); 2)点和正斜杠都没有被转义(但是反斜杠被转义;它太强大了,即使在[-\w.\\/]
子表达式内也不能单独存在)。
2)现在我们必须确保模式确实覆盖了整个字符串。我们使用所谓的锚点 - [...]
表示字符串的开头,^
作为结尾。并且,不要忘记我们的字符串可能包含一个或多个允许的符号(用$
量词表示)。因此模式变为:
+
3)最后一件事 - 我们必须阻止使用^[-\w.\\/]+$
和../
(前面有..\
或/
- 否则,如果\
序列也开始了字符串。
表达此规则的最简单方法是使用所谓的“negative lookahead”测试。它写在(?!...)子表达式中,并且(在本例中)描述了以下思想:'确保零个或多个符号的序列后面没有“斜线 - 两个点 - 斜线”序列':
..[/\\]
最后一件事实际上是将模式放入^(?!.*[\\/]\.{2}[\\/])(?!\.{2}[\\/])[-\w.\\/]+$
函数中:因为我们在正则表达式中使用preg_match
符号,我们可以选择另一组分隔符。在我的例子中,我选择了'#':
/
请参阅?这真的很容易。你只需从小事做起,逐步发展它们。