3

我有一个我写的python脚本,我需要移植到php。它递归搜索给定目录并基于正则表达式搜索构建字符串。我要移植的第一个功能如下。它需要一个正则表达式和一个基本目录,递归地在该目录中的所有文件中搜索正则表达式,并构建一个字符串匹配列表。

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。我从网上抓取了一些目录遍历代码,由于我完全缺乏 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 文件,您应该使用“mb_ereg_match”函数而不是“preg_match”函数。
  • 它不遵循符号链接

总之,即使它根本不是最有效的解决方案,它也应该有效。

于 2012-10-30T22:11:39.237 回答