2

次の2つのルールのパス文字列を検証(preg_match)するためにRegExpをビルドしようとしています。

  1. パスは、指定された範囲のシンボルのみで構成されている必要があります[a-zA-z0-9-_\///\.]
  2. パスは、アップディレクトリシーケンス「..」で構成されません。

これは正しいパスの例です。/user/temp

そして悪いもの:/../user

UPD: /user/temp.../foo これも正しいでしょう(Laurence Gonsalvesに感謝します)

4

1 に答える 1

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

私は実際にこのパターンを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.\\/]+$#';

見る?本当に簡単です。)小さなことから始めて、徐々に発展させていきます。

于 2012-11-06T22:29:26.320 に答える