模板引擎与正则表达式[关闭]

i want to wrote a simple template engine

i have a html template file :

<!DOCTYPE html>
<html>
<head>
<title>title</title>
</head>
<body>
    <loop "loop_name">
        content
        <loop "loop_name2">
            content2
        </loop "loop_name2">
    </loop "loop_name">
</body>
</html>

i need to find all loops and subloops with regular expression and replace them with my predefined php variables

i wrote this but i know this is wrong way

preg_match_all("/\<loop \"(.*)\"\>(.*)\<\/loop \"(.*)\"\>/", $template_file_text, $matches);
print_r($matches);

any answers will be appreciated

REGEX is not capable of finding opening and matching ending tags in a way that you proably need it. Sidefact: This is something you might get ask if one wants to test your knowledge.

You could use a XML parser. See: http://php.net/manual/de/book.xml.php

If you want to implement this on your own than you could use a stack based algorithm that puts any opening element to a stack and pops it if you reach the matching ending tag. If you want to parse many html pages you better take the XML parser way that is built in in PHP since you will proably have to handle many situations where the page is not proverly written and error handling will become quite frustrating.

To improve performance you could cache the output file.

Off the top of my head you could try something like this. I would only use this method for non-loops tbh as you would still need to loop the data, and that's where things get complicated.

$data = array(
    'loop'    => array(
        'subloop'  =>  array()
    ),
    'another'    => array()
);

public function parse($data, $template)
{
    $callback = function($matches) use ($data)
    {
        return isset( $data[$matches[1]] )
               ? $data[$matches[1]]
               : $matches[0]
    };

    return preg_replace_callback('/\@(.*?)\@/', $callback, $template)
}

You can now see where the problem lies.

<body>
    @loop@
        @subloop@


    @another@
</body>