PHP生成正則表達式的類

正則表達式,寫起來仍是比較費勁的,因而封裝個類,初稿,拋磚引玉。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);

相關文章
相關標籤/搜索