次の2つのルールのパス文字列を検証(preg_match)するためにRegExpをビルドしようとしています。
- パスは、指定された範囲のシンボルのみで構成されている必要があります
[a-zA-z0-9-_\///\.]
- パスは、アップディレクトリシーケンス「..」で構成されません。
これは正しいパスの例です。/user/temp
そして悪いもの:/../user
UPD:
/user/temp.../foo
これも正しいでしょう(Laurence Gonsalvesに感謝します)
次の2つのルールのパス文字列を検証(preg_match)するためにRegExpをビルドしようとしています。
[a-zA-z0-9-_\///\.]
これは正しいパスの例です。/user/temp
そして悪いもの:/../user
UPD:
/user/temp.../foo
これも正しいでしょう(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
私は実際にこのパターンを3つのステップで作成しました。
1)与えられた最初のルールは、文字列で許可される記号は、、、0-9
(アンダースコア)、(ハイフン)、(ドット)、および両方のスラッシュ(および)であると述べています。最初の3つの位置はショートカット()で表すことができ、その他の位置には文字クラスが必要です。a-zA-Z
_
-
.
/
\
\w
[-\w.\\/]
ここで2つのことに注意してください。1)ハイフンは、文字クラスの最初または最後の記号である必要があります(そうでない場合は、範囲を定義するために使用されるメタ文字として扱われます)。2)ドットスラッシュとスラッシュの両方がまだエスケープされていません(ただし、バックスラッシュはエスケープされています[...]
。サブエクスプレッション内であっても、強力すぎてそのままにしておくことはできません)。
2)ここで、パターンが実際に文字列全体をカバーしていることを確認する必要があります。私たちはいわゆるアンカーでそれを行います-^
文字列の始まり$
、終わりのために。また、文字列が1つ以上の許可された記号(+
数量詞で表される)で構成されている可能性があることを忘れないでください。したがって、パターンは次のようになります。
^[-\w.\\/]+$
3)最後にもう1つ../
、and (シーケンスが文字列を開始する場合はorが前に付くかどうか)も使用..\
しないようにする必要があります。/
\
..[/\\]
このルールを表現する最も簡単な方法は、いわゆる「ネガティブルックアヘッド」テストを使用することです。これは(?!...)部分式内に記述され、(この場合)次のアイデアを説明します。'0個以上の記号のシーケンスの後に「スラッシュ-2ドット-スラッシュ」シーケンスが続かないようにしてください':
^(?!.*[\\/]\.{2}[\\/])(?!\.{2}[\\/])[-\w.\\/]+$
最後に、パターンを実際にpreg_match
機能さ/
せることです。正規表現内でシンボルを使用するため、別の区切り文字のセットを選択するだけです。私の例では、「#」を選択しました。
$pattern = '#^(?!.*[\\/]\.{2}[\\/])(?!\.{2}[\\/])[-\w.\\/]+$#';
見る?本当に簡単です。)小さなことから始めて、徐々に発展させていきます。