Php 使用regex解析嵌套的IF语句

Php 使用regex解析嵌套的IF语句,php,regex,templates,Php,Regex,Templates,我正在以学习和爱好的名义开发自己的模板引擎。我有一个正则表达式,它使用与TWIG几乎相同的语法查找if语句 您可以通过几个工作示例查看正则表达式,然后是我正在尝试使用的示例 以下是正则表达式: {%\s*if\s+(?<var>(?:[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)(?:\.(?:[a-zA-Z0-9_\x7f-\xff]*))*)\s(?:(?<operation>=|!=|<=|<|>=|>)\

我正在以学习和爱好的名义开发自己的模板引擎。我有一个正则表达式,它使用与TWIG几乎相同的语法查找if语句

您可以通过几个工作示例查看正则表达式,然后是我正在尝试使用的示例

以下是正则表达式:

{%\s*if\s+(?<var>(?:[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)(?:\.(?:[a-zA-Z0-9_\x7f-\xff]*))*)\s(?:(?<operation>=|!=|<=|<|>=|>)\s(?<var2>(?:(?:(?1)*)(?:\.(?:(?2)*))*)|(?:[0-9]+))\s?)?%}(?<if>(?:(?!{% e(?:lse|nd if) %}).)*)(?:{%\h?else\h?%}(?<else>[\s\S]*?))?{%\h?end if\s?%}
基本上,我希望正则表达式搜索最后一个{%end if%}标记,并将两者之间的所有内容作为字符串使用,以便以后递归解析


另外,作为旁注,将问题的大部分信息保留在regex tester的链接中是否合适?或者我应该把问题的大部分抄写在这里吗

bool bStopOnError = false;
regex RxCore(".....");

bool ParseCore( string sCore, int nLevel )
{
    // Locals
    bool bFoundError = false; 
    bool bBeforeElse = true;
    match _matcher;

    while ( search ( core, RxCore, _matcher ) )
    {
      // Content
        if ( _matcher["Content"].matched == true )
          // Print non-keyword content
          print ( _matcher["Content"].str() );

          // OR, Analyze content.
          // If this 'content' has error's and wish to return.
          // if ( bStopOnError )
          //   bFoundError = true;

        else
      // Else 
        if ( _matcher["Else"].matched == true )
        {
            // Check if we are not in a recursion
            if ( nLevel <= 0 )
            {
               // Report error, this 'else' is outside an 'if/end if' block
               // ( note - will only occur when nLevel == 0 )
               print ("\n>> Error, 'else' not in block " + _matcher["Else"].str() + "\n";

               // If this 'else' error will stop the process.
               if ( bStopOnError == true )
                  bFoundError = true;
            }
            else
            {
                // Here, we are inside a core recursion.
                // That means there can only be 1 'else'.
                // Print 'else'.
                print ( _matcher["Else"].str() );

                // Set the state of 'else'. 
                bBeforeElse == false;   
            }
        }

        else
      // Error ( will only occur when nLevel == 0 )
        if ( _matcher["Error"].matched == true )
        {
            // Report error 
            print ("\n>> Error, unbalanced " + _matcher["Error"].str() + "\n";
            // // If this unbalanced 'if/end if' error will stop the process.
            if ( bStopOnError == true )
                bFoundError = true;
        }

        else
      // IF/END IF block
        if ( _matcher["Begin"].matched == true )
        {
            // Analyze 'if content' for error and wish to return.
            string sIfContent = _matcher["If_Content"].str();
            // if ( bStopOnError )
            //   bFoundError = true;
            // else
            // {            
                 // Print 'begin' ( includes 'if content' )
                 print ( _matcher["Begin"].str() );

                 //////////////////////////////
                 // Recurse a new 'core'
                 bool bResult = ParseCore( _matcher["Core"].str(), nLevel+1 );
                 //////////////////////////////

                 // Check recursion result. See if we should unwind.
                 if ( bResult == false && bStopOnError == true )
                     bFoundError = true;
                 else
                     // Print 'end'
                     print ( _matcher["End"].str() );
            // }
        }
        else 
        {
           // Reserved placeholder, won't get here at this time.
        }

      // Error-Return Check
         if ( bFoundError == true && bStopOnError == true )
             return false;
    }

    // Finished this core!! Return true.
    return true;
}

///////////////////////////////
// Main

string strInitial = "...";

bool bResult = ParseCore( strInitial, 0 );
if ( bResult == false )
   print ( "Parse terminated abnormally, check messages!\n" );
由于您正在进行实验,经过一些胡闹之后,为您设计了一个通用正则表达式

这可能会增加你目前的知识,并提供一些基础

简介:

bool bStopOnError = false;
regex RxCore(".....");

bool ParseCore( string sCore, int nLevel )
{
    // Locals
    bool bFoundError = false; 
    bool bBeforeElse = true;
    match _matcher;

    while ( search ( core, RxCore, _matcher ) )
    {
      // Content
        if ( _matcher["Content"].matched == true )
          // Print non-keyword content
          print ( _matcher["Content"].str() );

          // OR, Analyze content.
          // If this 'content' has error's and wish to return.
          // if ( bStopOnError )
          //   bFoundError = true;

        else
      // Else 
        if ( _matcher["Else"].matched == true )
        {
            // Check if we are not in a recursion
            if ( nLevel <= 0 )
            {
               // Report error, this 'else' is outside an 'if/end if' block
               // ( note - will only occur when nLevel == 0 )
               print ("\n>> Error, 'else' not in block " + _matcher["Else"].str() + "\n";

               // If this 'else' error will stop the process.
               if ( bStopOnError == true )
                  bFoundError = true;
            }
            else
            {
                // Here, we are inside a core recursion.
                // That means there can only be 1 'else'.
                // Print 'else'.
                print ( _matcher["Else"].str() );

                // Set the state of 'else'. 
                bBeforeElse == false;   
            }
        }

        else
      // Error ( will only occur when nLevel == 0 )
        if ( _matcher["Error"].matched == true )
        {
            // Report error 
            print ("\n>> Error, unbalanced " + _matcher["Error"].str() + "\n";
            // // If this unbalanced 'if/end if' error will stop the process.
            if ( bStopOnError == true )
                bFoundError = true;
        }

        else
      // IF/END IF block
        if ( _matcher["Begin"].matched == true )
        {
            // Analyze 'if content' for error and wish to return.
            string sIfContent = _matcher["If_Content"].str();
            // if ( bStopOnError )
            //   bFoundError = true;
            // else
            // {            
                 // Print 'begin' ( includes 'if content' )
                 print ( _matcher["Begin"].str() );

                 //////////////////////////////
                 // Recurse a new 'core'
                 bool bResult = ParseCore( _matcher["Core"].str(), nLevel+1 );
                 //////////////////////////////

                 // Check recursion result. See if we should unwind.
                 if ( bResult == false && bStopOnError == true )
                     bFoundError = true;
                 else
                     // Print 'end'
                     print ( _matcher["End"].str() );
            // }
        }
        else 
        {
           // Reserved placeholder, won't get here at this time.
        }

      // Error-Return Check
         if ( bFoundError == true && bStopOnError == true )
             return false;
    }

    // Finished this core!! Return true.
    return true;
}

///////////////////////////////
// Main

string strInitial = "...";

bool bResult = ParseCore( strInitial, 0 );
if ( bResult == false )
   print ( "Parse terminated abnormally, check messages!\n" );
在纯正则表达式解决方案中,平衡文本的概念大约是
一个正则表达式引擎坏了。它不会填充细节。
为此,你必须自己动手

与下降解析器等相比,这是一种缓慢的方法。
不同之处在于,它不需要放松就能知道它在哪里。
因此,这将允许您在遇到错误时继续解析。
从过去的错误中获得更多的意义,以帮助调试

在执行此类操作时,您应该解析每个字符。
因此,我们解析内容、分隔符begin、core、end和错误

在本例中,我们在外部范围中留出7个捕获组来浏览信息

内容
-它由除
if/else/end if
以外的任何内容组成

Else
-这是
Else
语句

开始
-这是if块的开始

If_内容
-这是
If块内容

Core
-这是
外部开始和结束之间的全部。也包含嵌套内容

End
-这是外部
End if

错误
-这是不平衡错误,如果
,则为
;如果
,则为
结束

用法:

bool bStopOnError = false;
regex RxCore(".....");

bool ParseCore( string sCore, int nLevel )
{
    // Locals
    bool bFoundError = false; 
    bool bBeforeElse = true;
    match _matcher;

    while ( search ( core, RxCore, _matcher ) )
    {
      // Content
        if ( _matcher["Content"].matched == true )
          // Print non-keyword content
          print ( _matcher["Content"].str() );

          // OR, Analyze content.
          // If this 'content' has error's and wish to return.
          // if ( bStopOnError )
          //   bFoundError = true;

        else
      // Else 
        if ( _matcher["Else"].matched == true )
        {
            // Check if we are not in a recursion
            if ( nLevel <= 0 )
            {
               // Report error, this 'else' is outside an 'if/end if' block
               // ( note - will only occur when nLevel == 0 )
               print ("\n>> Error, 'else' not in block " + _matcher["Else"].str() + "\n";

               // If this 'else' error will stop the process.
               if ( bStopOnError == true )
                  bFoundError = true;
            }
            else
            {
                // Here, we are inside a core recursion.
                // That means there can only be 1 'else'.
                // Print 'else'.
                print ( _matcher["Else"].str() );

                // Set the state of 'else'. 
                bBeforeElse == false;   
            }
        }

        else
      // Error ( will only occur when nLevel == 0 )
        if ( _matcher["Error"].matched == true )
        {
            // Report error 
            print ("\n>> Error, unbalanced " + _matcher["Error"].str() + "\n";
            // // If this unbalanced 'if/end if' error will stop the process.
            if ( bStopOnError == true )
                bFoundError = true;
        }

        else
      // IF/END IF block
        if ( _matcher["Begin"].matched == true )
        {
            // Analyze 'if content' for error and wish to return.
            string sIfContent = _matcher["If_Content"].str();
            // if ( bStopOnError )
            //   bFoundError = true;
            // else
            // {            
                 // Print 'begin' ( includes 'if content' )
                 print ( _matcher["Begin"].str() );

                 //////////////////////////////
                 // Recurse a new 'core'
                 bool bResult = ParseCore( _matcher["Core"].str(), nLevel+1 );
                 //////////////////////////////

                 // Check recursion result. See if we should unwind.
                 if ( bResult == false && bStopOnError == true )
                     bFoundError = true;
                 else
                     // Print 'end'
                     print ( _matcher["End"].str() );
            // }
        }
        else 
        {
           // Reserved placeholder, won't get here at this time.
        }

      // Error-Return Check
         if ( bFoundError == true && bStopOnError == true )
             return false;
    }

    // Finished this core!! Return true.
    return true;
}

///////////////////////////////
// Main

string strInitial = "...";

bool bResult = ParseCore( strInitial, 0 );
if ( bResult == false )
   print ( "Parse terminated abnormally, check messages!\n" );
在宿主程序中,定义一个名为
ParseCore()

此函数需要传递(或知道)当前核心字符串。
如果是C++,则将通过开始和结束字符串迭代器。 无论如何,字符串必须是函数的本地字符串

在此函数中,坐在while循环中解析字符串。
在每一场比赛中,做一个if/else测试,看看上面哪个组匹配。
它只能是这些组合

内容


Else


开始,如果内容、核心、结束


错误

只有一个组对递归很重要。这就是
核心
组。
当该组匹配时,您对
ParseCore()
将核心字符串传递给它

重复此操作,直到不再匹配为止。
错误报告、创建结构树以及其他任何操作都可以完成
在该功能中。
您甚至可以在任何时候设置一个全局标志来解除递归调用
然后退出。比如说,你想在出现错误或类似情况时停止

注意:在最初调用
ParseCore()
时,您只需传入整个原始字符串即可开始解析

祝你好运

(3)其他州(其他州和其他州的其他州的其他州的其他州的其他州的其他州的其他州的其他州的其他州的其他州的其他州的其他州的其他州的其他州的代码)之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以之所以?>{%\s*if\s+(?&\ifbody)\s*})(?:(?=)(?&\u core){%\s*end\s+if\s*}+(?(?>{%\s*(?:if\s+(?&\ifbody)| end\s+if | else)\s*])) (?s)#点所有修改器 # ===================== #外窥镜 # --------------- (?: (?#(1),非关键字内容 (?&_内容) ) |#或, # -------------- (?#(2),其他 (?&U其他) ) |#或 # -------------- (?#(3),如果 {%\s*如果\s+ (?#(4),如果内容 (?&ifu-body) ) \s*%} ) (?#(5),核心 (?&_核心) | ) (? # (6) {%\s*end\s+if\s*%}#end if ) |#或 # -------------- (?#(7),如果不平衡或如果结束 (?&_关键字) ) ) # ===================== #子程序 # --------------- (?(定义) #如果主体---------------------- (? # (8) (?> (?! %} ) . )+ ) #_uu_uu核心------------------------- (? # (9) (?> # #内容(非关键词) (? # (10) (?> (?!(?&_关键字)) . )+ ) | # #还有别的吗 #守卫:只有一个“其他” #允许在这个核心!! (?() (?!) ) (? # (11) (?>{%\s*else\s*%}) ) | # #IF(块启动) (?> {%\s*如果\s+ (?&ifu-body)