自己做了个小程序,很像将模板和代码分离开来
感觉dede的很不错,于是试着做了下,但是现在在循环这里卡住了
比如{pt:list  row='次数' 其他参数}
内容
{/pt:list}这个替换正则应该如何去做呢?ps:这个程序太小了,所以不是太想用smarty模板引擎

解决方案 »

  1.   

    把循环的内容也写成一个模板,在PHP用循环来控制,应该可以 
      

  2.   

    我一直用 <?phpforeach?>这种原生方式。
      

  3.   

    原理和UBB代码模式差不多。
    看看UBB的吧
      

  4.   

    {pt:list 参数}  替换成 <?php for(参数替换成有效语法) : ?>
    {/pt:list}      替换成 <?php endfor; ?>
    这样就可以忽略大括号{ }号了,好处理很多。因为
    for($i=0;$i<10;$i++)
    {
      echo $i;
    }
    等价于
    for($i=0;$i<10;$i++):
      echo $i;
    endfor;foreach类似。
      

  5.   


    <?php
    $s = <<<html
    <html>
    <head>
    </head>
    <body>
    {pt:list  row='3'}
    <a href="[list:href]">[list:title]</a>
    {/pt:list}
    fdsafdasf
    das
    f
    asdf
    asd
    f
    {pt:list  row='5'}
    <a href="[list:href]">[list:title]</a>
    {/pt:list}
    </body>
    html;$arrURL = array(
    0=>array(
    'href'=>'www.baidu.com',
    'title'=>'百度'
    ),
    1=>array(
    'href'=>'www.baidu.com',
    'title'=>'谷歌'
    )
    );
    class PtTagParse   
    {   
        var $NameSpace = 'pt';   
        var $TagStartWord = '{';    
        var $TagEndWord = '}';   
        var $TagMaxLen = 64;    
        var $SourceString = '';  
        var $tagArr = array();   
        var $count = 0;
        var $argsArr = array();     
        
        function ParseTemplet() {   
           
            $TagStartWord = $this->TagStartWord;   
            $TagEndWord = $this->TagEndWord;   
            $sPos = 0; $ePos = 0;   
               
            $FullTagStartWord =  $TagStartWord.$this->NameSpace.":";   
            $sTagEndWord =  $TagStartWord."/".$this->NameSpace.":";   
            $eTagEndWord = "/".$TagEndWord;   
            $tsLen = strlen($FullTagStartWord);   
            $sourceLen=strlen($this->SourceString);   
               
            if( $sourceLen <= ($tsLen + 3) )   
            {   
                return;   
            }   
                  
            for($i=0; $i < $sourceLen; $i++)   
            {   
                $tTagName = '';   
      
                if($i-1 >= 0)   
                {   
                    $ss = $i-1;   
                }   
                else  
                {   
                    $ss = 0;   
                }   
      
                $sPos = strpos($this->SourceString,$FullTagStartWord,$ss);   
                $isTag = $sPos;   
                   
                if($i==0)   
                {   
                    $headerTag = substr($this->SourceString,0,strlen($FullTagStartWord));   
                       
                    if($headerTag==$FullTagStartWord)   
                    {   
                        $isTag=true; $sPos=0;   
                    }   
                }   
      
                if($isTag===FALSE)   
                {   
                    break;   
                }               for($j=($sPos+$tsLen);$j<($sPos+$tsLen+$this->TagMaxLen);$j++)   
                {   
                    if($j>($sourceLen-1))   
                    {   
                        break;   
                    }   
                    else if( ereg("[/ \t\r\n]",$this->SourceString[$j]) || $this->SourceString[$j] == $this->TagEndWord )   
                    {   
                        break;   
                    }   
                    else  
                    {   
                        $tTagName .= $this->SourceString[$j];   
                    }   
                }   
      
                if($tTagName!='')   
                {   
                    $i = $sPos+$tsLen;   
                    $endPos = -1;   
                    $fullTagEndWordThis = $sTagEndWord.$tTagName.$TagEndWord;   
                       
                    $e1 = strpos($this->SourceString,$eTagEndWord, $i);   
                    $e2 = strpos($this->SourceString,$FullTagStartWord, $i);   
                    $e3 = strpos($this->SourceString,$fullTagEndWordThis,$i);   
                       
                    //$eTagEndWord = /} $FullTagStartWord = {tag: $fullTagEndWordThis = {/tag:xxx]   
                       
                    $e1 = trim($e1); $e2 = trim($e2); $e3 = trim($e3);   
                    $e1 = ($e1=='' ? '-1' : $e1);   
                    $e2 = ($e2=='' ? '-1' : $e2);   
                    $e3 = ($e3=='' ? '-1' : $e3);   
                    //not found '{/tag:'   
                    if($e3==-1)    
                    {   
                        $endPos = $e1;   
                        $elen = $endPos + strlen($eTagEndWord);   
                    }   
                    //not found '/}'   
                    else if($e1==-1)    
                    {   
                        $endPos = $e3;   
                        $elen = $endPos + strlen($fullTagEndWordThis);   
                    }   
                    //found '/}' and found '{/Pt:'   
                    else  
                    {   
                        //if '/}' more near '{Pt:'、'{/Pt:' , end tag is '/}', else is '{/Pt:'   
                        if($e1 < $e2 &&  $e1 < $e3 )   
                        {   
                            $endPos = $e1;   
                            $elen = $endPos + strlen($eTagEndWord);   
                        }   
                        else  
                        {   
                            $endPos = $e3;   
                            $elen = $endPos + strlen($fullTagEndWordThis);   
                        }   
                    }   
           
                    //not found end tag , error   
                    if($endPos==-1)   
                    {   
                        echo "Character postion $sPos, '$tTagName' Error!<br />\r\n";   
                        break;   
                    }   
                    $i = $elen;   
                    $ePos = $endPos;   
           
                   
                    $attStr = '';   
                    $innerText = '';   
                    $startInner = 0;   
                    for($j=($sPos+$tsLen);$j < $ePos;$j++)   
                    {   
                        if($startInner==0 && ($this->SourceString[$j]==$TagEndWord && $this->SourceString[$j-1]!="\\") )   
                        {   
                            $startInner=1;   
                            continue;   
                        }   
                        if($startInner==0)   
                        {   
                            $attStr .= $this->SourceString[$j];   
                        }   
                        else  
                        {   
                            $innerText .= $this->SourceString[$j];   
                        }   
                    }   
      
                    $this->count++;   
                    $this->tagArr[$this->count]['TagName'] = $tTagName;   
                    $this->tagArr[$this->count]['attStr'] = $attStr;   
                    $this->tagArr[$this->count]['StartPos'] = $sPos;   
                    $this->tagArr[$this->count]['EndPos'] = $endPos;   
                    $this->tagArr[$this->count]['innerText'] = $innerText;   
                    $this->tagArr[$this->count]['TagID'] = $this->count;      
                }   
                else  
                {   
                    $i = $sPos+$tsLen;   
                    break;   
                }   
            }        
        }
    //    function replaceSource() {
    //    
    //     foreach($this->tagArr as $arrTag) {
    //    
    //     if(isset($this->argsArr[$arrTag['TagName']])) {
    //    
    //     if(preg_match("/row=\'(.*?)\'/i", $arrTag['attStr'], $matches)) {
    //    
    //     for($i=0; $i<count($matches[1]); $i++) {
    //    
    //     str_ireplace('['.$arrTag['TagName'].':'.']', $arrTag['innerText'])
    //     }
    //     }
    //     }
    //     }
    //    }
        function assignArr($name, $arr) {
        
         $this->argsArr[$name] = $arr;
        }
    }   
    $parser = new PtTagParse();   
    $parser->SourceString = $s;  
    $parser->ParseTemplet();
    $parser->assignArr('list', $arrURL);   
    $parser->replaceSource();
    print_r($parser->tagArr);
    ?>
    下班了,先写到这里
      

  6.   

    织梦模板原理系列一 :http://blog.csdn.net/iseagold/archive/2010/04/22/5516809.aspx
      

  7.   

    $str = preg_replace("/\s*\{pt\:list\s+row\=\'(.+?)\'\}\s*(.+?)\s*\{\/pt\:list\}[\n\r\t]*/ies", "stripvtags('\n<?php for(\$i=0;\$i<\\1;\$i++){ ?> \\2 <?php } ?>\n')", str);
    function stripvtags($expr, $statement='') {
     $expr = str_replace("\\\"", "\"", preg_replace("/\<\?\=(\\\$.+?)\?\>/s", "\\1", $expr));
     $statement = str_replace("\\\"", "\"", $statement);
     return $expr.$statement;
    }
      

  8.   

    这是完整的代码,我本地测试OK了的!
    <?php
    //参数设置
    $dir = dirname(__FILE__);
    $tplfile = $dir."./template.htm";
    $cachefile = "./template.php";//读取内容
    if(!@$fp = fopen($tplfile, 'r')) exit('Not found!');
    $htmlstr = fread($fp, filesize($tplfile));
    fclose($fp);/*  标签样式
    /*  {pt:list row='5'}
    /*  内容设置
    /*  {/pt:list}    *///替换内容
    $htmlstr = preg_replace("/\s*\{pt\:list\s+row\=\'(.+?)\'\}\s*(.+?)\s*\{\/pt\:list\}[\n\r\t]*/ies",
                            "strrptags('\n<?php\nfor(\$i=0;\$i<\\1;\$i++){\n?>\n\\2\n<?php\n}\n?>\n')",
                             $htmlstr
    );$htmlstr = trim($htmlstr);//写缓存文件
    if(!@$fp = fopen($dir.$cachefile, 'w')) exit('Have no access to write!');
    flock($fp, 2);
    fwrite($fp, $htmlstr);
    fclose($fp);//显示内容
    include $cachefile;//正则表达式匹配替换
    function strrptags($expr) {
      $expr = str_replace("\\\"", "\"", $expr);
      return $expr;
    }
    ?>
      

  9.   


    <?php
    $s = <<<html
    <html>
    <head>
    </head>
    <body>
    {pt:list  row='3'}
    <a href="[list:href]">[list:title]</a>
    {/pt:list}
    fdsafdasf
    <hr>分割线================================</hr>
    das
    f
    asdf
    asd
    f
    {pt:list  row='5'}
    <a href="[list:href]">[list:title]</a>
    {/pt:list}
    再来六条
    {pt:list  row='6'}
    <a href="[list:href]">[list:title]</a>
    {/pt:list}
    </body>
    </html>
    html;$arrURL = array(
    0=>array(
    'href'=>'www.baidu.com',
    'title'=>'百度'
    ),
    1=>array(
    'href'=>'www.baidu.com',
    'title'=>'谷歌'
    ),
    2=>array(
    'href'=>'www.msn.com',
    'title'=>'msn'
    ),
    3=>array(
    'href'=>'www.qq.com',
    'title'=>'qq'
    ),
    4=>array(
    'href'=>'www.ibm.com',
    'title'=>'ibm'
    ),
    5=>array(
    'href'=>'www.lincostore.com',
    'title'=>'lincostore'
    )
    );
    class PtTagParse   
    {   
        var $NameSpace = 'pt';   
        var $TagStartWord = '{';    
        var $TagEndWord = '}';   
        var $TagMaxLen = 64;    
        var $SourceString = '';  
        var $tagArr = array();   
        var $count = 0;
        var $argsArr = array();     
        
        function ParseTemplet() {   
           
            $TagStartWord = $this->TagStartWord;   
            $TagEndWord = $this->TagEndWord;   
            $sPos = 0; $ePos = 0;   
               
            $FullTagStartWord =  $TagStartWord.$this->NameSpace.":";   
            $sTagEndWord =  $TagStartWord."/".$this->NameSpace.":";   
            $eTagEndWord = "/".$TagEndWord;   
            $tsLen = strlen($FullTagStartWord);   
            $sourceLen=strlen($this->SourceString);   
               
            if( $sourceLen <= ($tsLen + 3) )   
            {   
                return;   
            }   
                  
            for($i=0; $i < $sourceLen; $i++)   
            {   
                $tTagName = '';   
      
                if($i-1 >= 0)   
                {   
                    $ss = $i-1;   
                }   
                else  
                {   
                    $ss = 0;   
                }   
      
                $sPos = strpos($this->SourceString,$FullTagStartWord,$ss);   
                $isTag = $sPos;   
                   
                if($i==0)   
                {   
                    $headerTag = substr($this->SourceString,0,strlen($FullTagStartWord));   
                       
                    if($headerTag==$FullTagStartWord)   
                    {   
                        $isTag=true; $sPos=0;   
                    }   
                }   
      
                if($isTag===FALSE)   
                {   
                    break;   
                }               for($j=($sPos+$tsLen);$j<($sPos+$tsLen+$this->TagMaxLen);$j++)   
                {   
                    if($j>($sourceLen-1))   
                    {   
                        break;   
                    }   
                    else if( ereg("[/ \t\r\n]",$this->SourceString[$j]) || $this->SourceString[$j] == $this->TagEndWord )   
                    {   
                        break;   
                    }   
                    else  
                    {   
                        $tTagName .= $this->SourceString[$j];   
                    }   
                }   
      
                if($tTagName!='')   
                {   
                    $i = $sPos+$tsLen;   
                    $endPos = -1;   
                    $fullTagEndWordThis = $sTagEndWord.$tTagName.$TagEndWord;   
                       
                    $e1 = strpos($this->SourceString,$eTagEndWord, $i);   
                    $e2 = strpos($this->SourceString,$FullTagStartWord, $i);   
                    $e3 = strpos($this->SourceString,$fullTagEndWordThis,$i);   
                       
                    //$eTagEndWord = /} $FullTagStartWord = {tag: $fullTagEndWordThis = {/tag:xxx]   
                       
                    $e1 = trim($e1); $e2 = trim($e2); $e3 = trim($e3);   
                    $e1 = ($e1=='' ? '-1' : $e1);   
                    $e2 = ($e2=='' ? '-1' : $e2);   
                    $e3 = ($e3=='' ? '-1' : $e3);   
                    //not found '{/tag:'   
                    if($e3==-1)    
                    {   
                        $endPos = $e1;   
                        $elen = $endPos + strlen($eTagEndWord);   
                    }   
                    //not found '/}'   
                    else if($e1==-1)    
                    {   
                        $endPos = $e3;   
                        $elen = $endPos + strlen($fullTagEndWordThis);   
                    }   
                    //found '/}' and found '{/Pt:'   
                    else  
                    {   
                        //if '/}' more near '{Pt:'、'{/Pt:' , end tag is '/}', else is '{/Pt:'   
                        if($e1 < $e2 &&  $e1 < $e3 )   
                        {   
                            $endPos = $e1;   
                            $elen = $endPos + strlen($eTagEndWord);   
                        }   
                        else  
                        {   
                            $endPos = $e3;   
                            $elen = $endPos + strlen($fullTagEndWordThis);   
                        }   
                    }   
           
                    //not found end tag , error   
                    if($endPos==-1)   
                    {   
                        echo "Character postion $sPos, '$tTagName' Error!<br />\r\n";   
                        break;   
                    }   
                    $i = $elen;   
                    $ePos = $endPos;   
           
                   
                    $attStr = '';   
                    $innerText = '';   
                    $startInner = 0;   
                    for($j=($sPos+$tsLen);$j < $ePos;$j++)   
                    {   
                        if($startInner==0 && ($this->SourceString[$j]==$TagEndWord && $this->SourceString[$j-1]!="\\") )   
                        {   
                            $startInner=1;   
                            continue;   
                        }   
                        if($startInner==0)   
                        {   
                            $attStr .= $this->SourceString[$j];   
                        }   
                        else  
                        {   
                            $innerText .= $this->SourceString[$j];   
                        }   
                    }   
      
                    $this->count++;   
                    $this->tagArr[$this->count]['TagName'] = $tTagName;   
                    $this->tagArr[$this->count]['attStr'] = $attStr;   
                    $this->tagArr[$this->count]['StartPos'] = $sPos;   
                    $this->tagArr[$this->count]['EndPos'] = $endPos+strlen($fullTagEndWordThis);   
                    $this->tagArr[$this->count]['innerText'] = $innerText;   
                    $this->tagArr[$this->count]['TagID'] = $this->count;      
                }   
                else  
                {   
                    $i = $sPos+$tsLen;   
                    break;   
                }   
            }        
        }
        function replaceSource() {
        
         for($k=count($this->tagArr); $k>=0; $k--) {
    $str = '';
         if(isset($this->argsArr[$this->tagArr[$k]['TagName']])) {
        
         if(preg_match("@row=\'(.*?)\'@i", $this->tagArr[$k]['attStr'], $matches)) {     if(isset($matches[1])) {
        
         for($i=0; $i<$matches[1]; $i++) {
        
         $r1 = '[' . $this->tagArr[$k]['TagName'] . ':href' .  ']';
         $r2 = '[' . $this->tagArr[$k]['TagName'] . ':title' .  ']';
         $s = str_ireplace(
         array($r1, $r2), 
         array(
         $this->argsArr[$this->tagArr[$k]['TagName']][$i]['href'],
         $this->argsArr[$this->tagArr[$k]['TagName']][$i]['title']
         ), 
         $this->tagArr[$k]['innerText']
         );
         $str .= $s;
         }
        
         $this->tagArr[$k]['innerText'] = $str;
         $innerText = substr($this->SourceString, $this->tagArr[$k]['StartPos'], $this->tagArr[$k]['EndPos']-$this->tagArr[$k]['StartPos']);
         $this->SourceString = str_ireplace($innerText, $this->tagArr[$k]['innerText'], $this->SourceString);
         }
         }
         }
         }
        }
        function assignArr($name, $arr) {
        
         $this->argsArr[$name] = $arr;
        }
    }   
    $parser = new PtTagParse();   
    $parser->SourceString = $s;  
    $parser->ParseTemplet();
    $parser->assignArr('list', $arrURL);   
    $parser->replaceSource();
    print_r($parser->SourceString);
    ?>
    out:<html>
    <head>
    </head>
    <body>

    <a href="www.baidu.com">百度</a>

    <a href="www.baidu.com">谷歌</a>

    <a href="www.msn.com">msn</a>

    fdsafdasf
    <hr>分割线================================</hr>
    das
    f
    asdf
    asd
    f

    <a href="www.baidu.com">百度</a>

    <a href="www.baidu.com">谷歌</a>

    <a href="www.msn.com">msn</a>

    <a href="www.qq.com">qq</a>

    <a href="www.ibm.com">ibm</a>

    再来六条

    <a href="www.baidu.com">百度</a>

    <a href="www.baidu.com">谷歌</a>

    <a href="www.msn.com">msn</a>

    <a href="www.qq.com">qq</a>

    <a href="www.ibm.com">ibm</a>

    <a href="www.lincostore.com">lincostore</a>

    </body>
    </html>