正則表達式,寫起來仍是比較費勁的,因而封裝個類,初稿,拋磚引玉。html
關於正則,建議參考 https://github.com/CyC2018/CS-Notes/blob/master/notes/%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F.mdgit
class Pattern { public $pattern = ''; public static function init(){ return new static(); } public function start($char){ $this->pattern .= '^' . $char; return $this; } public function end($char){ $this->pattern .= $char . '$'; return $this; } //匹配次數 public function count($range = null){ if(is_array($range)) $range = implode(',', $range); if(is_numeric($range) || strpos($range, ',') ) $range = '{' . $range . '}'; $this->pattern .= $range; return $this; } public function match($pattern, $get = true){ $this->pattern .= '(' . ($get ? '' : '?:'). $pattern . ')'; return $this; } //轉義 public function escape($char){ $this->pattern .= '\\' . $char; return $this; } public function append($string, $comment = null){ $this->pattern .= $string; //$this->pattern .= $string . ($comment ? '(?#'. $comment .')' : ''); return $this; } public function flush(){ $pattern = $this->pattern; $this->pattern = ''; return $pattern; } public static function help(){ $help = <<<'help' [\b] => 單詞邊界 [\B] => 非單詞邊界 [\cx] => x 指明的控制字符,值必須爲 A-Z 或 a-z 之一 [\d] => 數字,[0-9] [\D] => 非數字,[^0-9]。 [\f] => 換頁符,等價於 \x0c 和 \cL [\n] => 標識一個八進制轉義值或一個向後引用。若是 \n 以前至少 n 個獲取的子表達式,則 n 爲向後引用。不然,若是 n 爲八進制數字 (0-7),則 n 爲一個八進制轉義值。 [\r] => 回車符,等價於 \x0d 和 \cM [\s] => 空白字符,等價於 [\f\n\r\t\v] [\S] => 非空白字符,等價於 [^\f\n\r\t\v] [\t] => 水平製表符,等價於 \x09 和 \cI [\v] => 垂直製表符。等價於 \x0b 和 \cK [\w] => 字母、數字、下劃線,等價於 [A-Za-z0-9_] [\W] => 非字母、非數字、非下劃線。等價於 [^A-Za-z0-9_] [\xn] => 匹配某個十六進制表示的字符,值必須爲肯定的兩個數字長。\x41B 表示 AB [\num] => 對所獲取的匹配的引用,"(.)\1" 匹配兩個連續的相同字符 [\nm] => 標識一個八進制轉義值或一個向後引用。若是 \nm 以前至少有 nm 個得到子表達式,則 nm 爲向後引用。若是 \nm 以前至少有 n 個獲取,則 n 爲一個後跟文字 m 的向後引用。若是前面的條件都不知足,若 n 和 m 均爲八進制數字 (0-7),則 \nm 將匹配八進制轉義值 nm [\nml] => 若是 n 爲八進制數字 (0-3),且 m 和 l 均爲八進制數字 (0-7),則匹配八進制轉義值 nml。 [\un] => n 是四個十六進制數字表示的 Unicode 字符 help; echo $help; } //正向查找 public function forward($string, $positive = true){ $this->pattern .= '(?' . ($positive ? '=' : '!') . $string . ')'; return $this; } //反向查找 public function backward($string, $positive = true){ $this->pattern .= '(?<' . ($positive ? '=' : '!') . $string . ')'; return $this; } public function exec($mode = null){ $mode = $mode ? $mode : ''; $pattern = '/' . $this->pattern . '/' . $mode; return $pattern; } //條件查找 public function condition($condition, $string){ $this->pattern .= '(?(' . $condition. ')'. $string .')'; return $this; } } $html = "<b>example: </b><div align=left>this is a test</div>"; $pattern = Pattern::init()->append('<(\w+?)', '標籤名') ->append('\s*?', '空格') ->append('.*?>','屬性') ->append('.*?', '內容') ->append('<\/\1>', '回溯引用標籤名') ->exec(); echo $pattern . "\n"; preg_match_all($pattern, $html, $out); print_r($out);