11

簡単に言うと、私はアクセス制御システムを書きました。

このシステムの要件の 1 つは、正規化/正規化されたパスにアクセスできるかどうかをパターンと照合してチェックすることです。

最初に考えられるのは PREG です。問題は、パターンがファイルベースであることです。つまり、glob(). 基本的には、?(任意の 1 文字に一致) または*(任意の文字に一致) を含むパターンだけです。

簡単に言えば、glob()PHP で の一致する機能を再作成する必要があります。

サンプルコード:

function path_matches($path, $pattern){
    // ... ?
}

path_matches('path/index.php', 'path/*');        // true
path_matches('path2/', 'path/*');                // false
path_matches('path2/test.php', 'path2/*.php');   // true

$pattern考えられる解決策は、を使用するよりも正規表現に変換することpreg_match()ですが、他に方法はありますか?

注:正規表現を使用できない理由は、パターンが非プログラマーによって記述されるためです。

4

5 に答える 5

17

を使用するfnmatch()と、うまくいくようです。

于 2012-12-17T12:21:53.267 に答える
5

正規表現への変換は、私にとって最良の解決策のようです。、 、、に変換するだけ*です。ただし、物事を行う順序に関して鶏が先か卵が先かという問題があるため、見かけほど単純ではありません。.*?.preg_quote

私はこの解決策が好きではありませんが、私が思いつくことができる最高のものです:正規表現を使用して正規表現を生成します。

function path_matches($path, $pattern, $ignoreCase = FALSE) {

  $expr = preg_replace_callback('/[\\\\^$.[\\]|()?*+{}\\-\\/]/', function($matches) {
    switch ($matches[0]) {
      case '*':
        return '.*';
      case '?':
        return '.';
      default:
        return '\\'.$matches[0];
    }
  }, $pattern);

  $expr = '/'.$expr.'/';
  if ($ignoreCase) {
    $expr .= 'i';
  }

  return (bool) preg_match($expr, $path);

}

編集大文字と小文字を区別するオプションが追加されました。

動いているのを見る

于 2012-12-17T12:23:15.520 に答える
5

PHP には、PHP 4.3.0 以降に組み込まれている関数が既にあります。

fnmatch()渡された文字列が指定されたシェル ワイルドカード パターンと一致するかどうかを確認します。

于 2013-03-11T08:34:24.903 に答える
3

glob() の PHP ドキュメントから。とにかく preg_match が最善の解決策だと思います。

http://php.net/manual/en/function.glob.php

<?php   
function match_wildcard( $wildcard_pattern, $haystack ) {
   $regex = str_replace(
     array("\*", "\?"), // wildcard chars
     array('.*','.'),   // regexp chars
     preg_quote($wildcard_pattern)
   );

   return preg_match('/^'.$regex.'$/is', $haystack);
}

$test = "foobar and blob\netc.";
var_dump(
    match_wildcard('foo*', $test),      // TRUE
    match_wildcard('bar*', $test),      // FALSE
    match_wildcard('*bar*', $test),     // TRUE
    match_wildcard('**blob**', $test),  // TRUE
    match_wildcard('*a?d*', $test),     // TRUE
    match_wildcard('*etc**', $test)     // TRUE
);
?>
于 2012-12-17T12:27:34.907 に答える