正则表达式,删除标签不内容

时间:2016-05-21 08:10:45

标签: php regex template-engine

早上好

我正在开发一个模板类。 我会像这样在tpl文件中创建条件:

@if('eee' == 'esee')
  <h2>Test</h2>
@endif

@if('aaa' == 'aaa')
  <h2>Test</h2>
@endif

当条件为假时,所有隐藏的工作都是如此,但是我会删除@if('eee' == 'esee')@endif,但我不知道如何。

这是我的功能

private static function get_condition(){
    $control = array();
    preg_match_all('/@if\((?P<control>[^)]+)\)/', self::$viewMainContent, $control);
$matches = isset($control['control']) ? count($control['control']) : 0;
for($i = 0; $i < $matches; $i++) {
        $operators = [' == ', ' != ', ' >= ', ' <= ', ' > ', ' < '];
        foreach($operators as $operator){
            if(preg_match('/'.$operator.'/', $control['control'][$i])){
                $val = explode($operator, $control['control'][$i]);
                $param = preg_grep('/\'[^"]*\'/is', $val, PREG_SET_ORDER);
                $show = false;
                if(count($param) == 2){
                    switch(trim($operator)){
                        case "==":
                            if($param[0] == $param[1]){ $show = true; }
                            break;
                        case "!=":
                            if($param[0] != $param[1]){ $show = true; }
                            break;
                        case ">=":
                            if($param[0] >= $param[1]){ $show = true; }
                            break;
                        case "<=":
                            if($param[0] <= $param[1]){ $show = true; }
                            break;
                        case ">":
                            if($param[0] > $param[1]){ $show = true; }
                            break;
                        case "<":
                            if($param[0] < $param[1]){ $show = true; }
                            break;

                    }
                }

                self::$viewMainContent = str_replace("\n", " ", self::$viewMainContent);
                if(!$show){
                    self::$viewMainContent = preg_replace('/'.preg_quote($control[0][$i]).'(.*?)\@endif/', '', self::$viewMainContent);
                } else {
                    //self::$viewMainContent = preg_replace('/'.preg_quote($control[0][$i]).'/', '', self::$viewMainContent);
                    //self::$viewMainContent = preg_replace('/@endif/', '', self::$viewMainContent);
                }
            }
        }
}
}

如何在没有内容的情况下删除标签?

THX

1 个答案:

答案 0 :(得分:0)

真的不安全,但我在这里使用eval(),只是为了简单起见。您可以使用switch() case逻辑替换它。我认为实现你想要的方法之一是使用preg_replace_callback()

$template = <<<'EOD'
@if('eee' == 'eee')
  <h2>Test</h2>
@endif

@if('aaa' == 'aaa')
  <h2>Test</h2>
@endif
EOD;

$regex = '/@if\((?P<condition>.*)\)\n*\s*(?P<content>(?s:[\=\"\s\/\<\>\w\n]*))@endif/m';

preg_match_all($regex, $template, $matches);

$template = preg_replace_callback(
    $regex,
    function ($matches) {
        if (eval('return ' . $matches['condition'] . ';')) {
            return rtrim($matches['content']);
        }

        return '';
    },
    $template
);

var_dump($template);

这是demo

您还可以试用'/@if\((?P<condition>.*)\)\n*\s*(?P<content>(?s:[\=\"\s\/\<\>\w\n]*))@endif/m'正则表达式here