Re: ereg + performance problem

From: Date: Fri, 02 Jan 2004 09:59:44 +0000
Subject: Re: ereg + performance problem
References: 1  Groups: php.general 
Request: Send a blank email to php-general+get-173629@lists.php.net to get a copy of this message
Hi, I think that smarty [ http://smarty.php.net ] can do this for u. It has tag nesting and, of course, you can define your own tag as a plugin. As for performance problem - this is known "feature" of regexp. Solution is not simple. You, IMHO, have to rethink your approach. For parsing larger or complex files is much better to use state machine (finite state automaton). Try to search google for more theory. For ex. http://en.wikipedia.org/wiki/Finite_state_automaton Martin Helie wrote:
Hello, I'm writing a routine that recursively reads an HTML document, looking for "special tags". It's a template system, but contrary to what I've seen out there so far, no template engines allow for any kind of customization from within the document; they only seem to be variable replacement systems. What I have in mind is something along the lines of: <HTML>
    blah blah
    {MAGICTAG param1=a param2=b}some more {ANOTHERTAG}text{/ANOTHERTAG} here
{/MAGICTAG}
    blah
</HTML> The text between ANOTHERTAG would first be changed and then passed along with the other text to MAGICTAG. ie, the data is treated from the inside out, and nesting is obviously supported. I've got everything working, but the problem is I'm using quite a few "ereg" statements recursively, so performance is not so good. Here's a simplified version of the core (it's part of a class, and I modified the code for a "standalone" version here). Thanks in advance for any ideas. Feel free to recycle this code. function parse( $template ) {
    //Look for (before*) {a tag} (after*) anything and store matches in
$regs
    if( ereg( "(.*)[{]([a-zA-Z0-9]+)[}](.*)", $template, $regs ) ) {
        $before = $regs[1];
        $tag     = $regs[2];
        //Now look for (data*) {/closing tag} (after*) in the "after"
portion of first match
        if( ereg( "(.*)[{][/]" . $tag. "[}](.*)", $regs[3], $regs ) ) {
            $after = $regs[2];
            $data = $regs[1];
            $resolvedTag = initHandler( $tag, $data ); //handle this tag and
data
        }
        //support for "standalone" tags (no {/closing tag} )
        else {
            ereg( "(.*)", $regs[3], $regs );
            $resolvedTag = getTagValue( $tag );
            $after = $regs[1];
        }
    }
    if( $resolvedTag ) {
        $template =
        $before
        . $resolvedTag
        . $after;
        parse( $template );
    }
    else {
        return $template;
    }
}
-- Mirek Novak jabberID: mirek@njs.netlab.cz ICQ: 119499448

« previous php.general (#173629) next »