2012-10-29 30 views
3

我有一个我写的python脚本,我需要移植到php。它递归地搜索给定的目录并基于正则表达式搜索建立一个字符串。下面是我尝试移植的第一个函数。它需要一个正则表达式和一个基本目录,递归搜索该目录中的所有文件以获取正则表达式,并构建一个字符串匹配列表。从Python到PHP的GREP功能

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 

我从来不使用PHP,除了基本的GET参数操作。由于我完全缺乏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"; 
    } 
    } 
} 
+1

为什么不简单地在cli上使用grep? 'grep -d递归'你的字符串'? –

+0

看看[glob()](http://us2.php.net/manual/en/function.glob.php) –

+1

我点击这个PHP脚本通过一个http请求,并需要返回的值在一定格式,所以常规的grep将不起作用。将检查出glob()=。 – bitpshr

回答

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”函数。
  • 它一点儿也不遵循符号链接

总之,即使它不是最有效的解决方案的话,那应该工作。