检查目录路径中的符号范围和".."向上目录标志 [英] check directory path for symbols range and ".." up directory sign
问题描述
我尝试构建RegExp来验证(preg_match)以下两个规则的某些路径字符串:
I try to build RegExp to validate(preg_match) some path string for two following rules:
- 路径必须仅包含给定范围
[a-zA-z0-9-_\///\.]
中的符号
- 路径将不包含向上目录序列".."
- path must consists only symbols from given range
[a-zA-z0-9-_\///\.]
- path will not consist an up directory sequence ".."
这是正确的路径示例:/user/temp
this is a correct path example: /user/temp
和坏人:/../user
UPD:
/user/temp.../foo
也将是正确的(由于 Laurence Gonsalves )
UPD:
/user/temp.../foo
will also be correct (thanks to Laurence Gonsalves)
推荐答案
请考虑以下问题:
$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
我实际上已通过三个步骤构建了该模式:
I've actually built this pattern in three steps:
1)给出的第一条规则说,字符串中仅允许使用的符号为0-9
,a-zA-Z
,_
(下划线),-
(连字符),.
(点)和两个斜杠( /
和\
).前三个位置可以使用快捷方式(\w
)表示,其他三个则需要字符类:
1) the first rule given said that only symbols allowed in the string are 0-9
, a-zA-Z
, _
(underscore), -
(hyphen), .
(dot) and both slashes (/
and \
). First three positions can be expressed with a shortcut (\w
), others require a character class:
[-\w.\\/]
请注意两件事:1)连字符应为字符类中的第一个或最后一个符号(否则,它被视为用于定义范围的元字符); 2)点斜杠和正斜杠都尚未转义(尽管反斜杠已转义;它太强大了,即使在[...]
子表达式中也不能单独保留).
Note two things here: 1) hyphen should be either the first or the last symbol in the character class (otherwise it's treated as a metacharacter used to define a range); 2) both dot and forward slash are not escaped yet (backslash is escaped, though; it's too powerful to be left alone, even within [...]
subexpression).
2)现在我们必须确保模式确实覆盖了整个字符串.我们使用所谓的定位符-字符串的开头为^
,结尾为$
.并且,不要忘记我们的字符串可能包含一个或多个允许的符号(用+
量词表示).这样的模式就变成了这样:
2) now we have to make sure that the pattern does indeed cover the whole string. We do it with so-called anchors - ^
for beginning of the string, $
for the end. And, not to forget that our string may consist of one or more allowed symbols (this expressed with +
quantifier). So the pattern becomes this:
^[-\w.\\/]+$
3)最后一件事-我们也必须避免使用../
和..\
(如果..[/\\]
序列以字符串开头,则不要使用/
或\
开头).
3) one last thing - we have to prevent using ../
and ..\
(preceded by /
or \
- or not, if ..[/\\]
sequence begins the string) as well.
表达此规则的最简单方法是使用所谓的"否定前瞻"测试.它写在(?!...)子表达式中,并且(在这种情况下)描述了以下想法:确保零个或多个符号的序列后不跟斜线-两点-斜线"序列":>
The easiest way of expressing this rule is using so-called 'negative lookahead' test. It's written within (?!...) subexpression, and (in this case) describes the following idea: 'make sure that sequence of zero or more symbols is not followed by "slash-two dots-slash" sequence':
^(?!.*[\\/]\.{2}[\\/])(?!\.{2}[\\/])[-\w.\\/]+$
最后一件事实际上是将模式放入preg_match
函数中:由于我们在正则表达式中使用/
符号,因此我们可以选择另一组定界符.在我的示例中,我选择了#":
One last thing is actually placing the pattern into preg_match
function: as we use /
symbol within the regex, we can just choose another set of delimiters. In my example, I chose '#':
$pattern = '#^(?!.*[\\/]\.{2}[\\/])(?!\.{2}[\\/])[-\w.\\/]+$#';
看到了吗?真的很简单. )您只需要从小事情开始并逐步发展它们.
See? It's real easy. ) You just have to start from small things and gradually develop them.
这篇关于检查目录路径中的符号范围和".."向上目录标志的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!