2012-10-29 72 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」函數。
  • 它一點兒也不遵循符號鏈接

總之,即使它不是最有效的解決方案的話,那應該工作。