3

PHPに移植する必要があることを書いたPythonスクリプトがあります。指定されたディレクトリを再帰的に検索し、正規表現検索に基づいて文字列を作成します。私が移植しようとしている最初の機能は以下のとおりです。正規表現とベースディレクトリを取り、そのディレクトリ内のすべてのファイルで正規表現を再帰的に検索し、一致する文字列のリストを作成します。

def grep(regex, base_dir):
    matches = list()
    for path, dirs, files in os.walk(base_dir):
        for filename in files:
            fullpath = os.path.join(path, filename)
            with open(fullpath, 'r') as f:
                content = f.read()
                matches = matches + re.findall(regex, content)
    return matches

基本的な GET パラメータ操作を除いて、PHP を使用することはありません。Web からいくつかのディレクトリ ウォーキング コードを取得しましたが、php API がまったくないため、上記の python 関数のように機能させるのに苦労しています。

function findFiles($dir = '.', $pattern = '/./'){
  $prefix = $dir . '/';
  $dir = dir($dir);
  while (false !== ($file = $dir->read())){
    if ($file === '.' || $file === '..') continue;
    $file = $prefix . $file;
    if (is_dir($file)) findFiles($file, $pattern);
    if (preg_match($pattern, $file)){
      echo $file . "\n";
    }
  }
}
4

1 に答える 1

1

これが私の解決策です:

<?php 

class FileGrep {
    private $dirs;      // Scanned directories list
    private $files;     // Found files list
    private $matches;   // Matches list

    function __construct() {
        $this->dirs = array();
        $this->files = array();
        $this->matches = array();
    }

    function findFiles($path, $recursive = TRUE) {
        $this->dirs[] = realpath($path);
        foreach (scandir($path) as $file) {
            if (($file != '.') && ($file != '..')) {
                $fullname = realpath("{$path}/{$file}");
                if (is_dir($fullname) && !is_link($fullname) && $recursive) {
                    if (!in_array($fullname, $this->dirs)) {
                        $this->findFiles($fullname, $recursive);
                    }
                } else if (is_file($fullname)){
                    $this->files[] = $fullname;
                }
            }
        }
        return($this->files);
    }

    function searchFiles($pattern) {
        $this->matches = array();
        foreach ($this->files as $file) {
            if ($contents = file_get_contents($file)) {
                if (preg_match($pattern, $contents, $matches) > 0) {
                    //echo $file."\n";
                    $this->matches = array_merge($this->matches, $matches);
                }
            }
        }
        return($this->matches);
    }
}


// Usage example:

$fg = new FileGrep();
$files = $fg->findFiles('.');               // List all the files in current directory and its subdirectories
$matches = $fg->searchFiles('/open/');      // Search for the "open" string in all those files

?>
<html>
    <body>
        <pre><?php print_r($matches) ?></pre>
    </body>
</html>

を注意:

  • 各ファイルを読み取ってパターンを検索するため、大量のメモリが必要になる場合があります (PHP.INI ファイルの「memory_limit」構成を確認してください)。
  • Unicode ファイルでは機能しません。Unicode ファイルを扱う場合は、「preg_match」関数ではなく「mb_ereg_match」関数を使用する必要があります。
  • シンボリックリンクをたどらない

結論として、たとえそれが最も効率的なソリューションでなくても、うまくいくはずです。

于 2012-10-30T22:11:39.237 に答える