gpt4 book ai didi

php - 正则表达式 - 获取元素以呈现 if 语句

转载 作者:可可西里 更新时间:2023-11-01 12:50:31 24 4
gpt4 key购买 nike

我正在设计脚本并尝试在 php 中不使用 eval 构建 if 结构。

仍然不完整,但正在突破,它是为了做一个模板引擎,引擎的“if”部分。不允许赋值运算符,但我需要测试值不允许 php 代码注入(inject),准确地说不使用 eval 它需要在变量之间进行单独的操作以防止注入(inject)攻击。

正则表达式必须捕获

[if:(a+b-c/d*e)|(x-y)&!(z%3=0)]
output
[elseif:('b'+'atman'='batman')]
output2
[elseif:('b'+'atman'='batman')]
output3
[elseif:('b'+'atman'='batman')]
output4
[else]
output5
[endif]

[if:(a+b-c/d*e)|(x-y)&!(z%3=0)]
output6
[else]
output7
[endif]

下面的代码用于获取 if、elseif、else 和 endif block 以及条件语句:

$regex = '^\h*\[if:(.*)\]\R(?<if>(?:(?!\[elseif)[\s\S])+)\R^\h*\[elseif:(.*)\]\R(?<elseif>(?:(?!\[else)[\s\S])+)\R^\h*\[else.*\]\R(?<else>(?:(?!\[endif)[\s\S])+)\R^\[endif\]~xm';

请帮助选择可选的 elseif 和 else。

然后使用条件语句,我可以获得操作:

$regex = '~([^\^=<>+\-%/!&|()*]+)([\^+\-%/!|&*])([^\^=<>+\-%/!&|()*]*)~';

然而,它只会将它们配对,缺少每个第 3 个运算符......

感谢您的帮助。

最佳答案

(编辑在底部添加了一个简单的if/elseif主体解析正则表达式)

使用 PCRE,我认为这个正则表达式递归应该处理嵌套
if/elseif/else/endif 构造。

在当前形式下,它是一个松散解析,因为它没有定义
[if/elseif: body ] 的形式非常好。
例如,[if: 是开始的定界符结构而 ] 是结束的吗?如果发生错误等。如果需要严格解析,可以通过这种方式完成。
现在它基本上是使用 [if: body ] 作为开始分隔符
[endif] 作为查找嵌套结构的结束定界符。

此外,它松散地将 body 定义为 [^\]]*,在认真的解析中
情况,必须充实以说明报价和其他内容。
就像我说的那样,将它拆开是可行的,但远不止于此
涉及。我已经在语言层面上做到了这一点,这并不简单。

底部有宿主语言使用伪代码示例。
语言递归演示了如何提取嵌套内容
正确。

正则表达式匹配核心的当前外壳核心
是内部嵌套内容。

对 ParseCore() 的每次调用都是在 ParseCore() 本身内部发起的
(除了 main() 的初始调用。

由于范围似乎未指定,我做了可以看到的假设
乱七八糟的评论。

捕获的 if/elseif 主体有一个占位符
然后可以针对 (operations) 部分进行解析,这实际上是第 2 部分
我还没有抽出时间做这个练习。
注意 - 我会尝试这样做,但我今天没有时间。

如果你有任何问题,请告诉我......

(?s)(?:(?<Content>(?&_content))|\[elseif:(?<ElseIf_Body>(?&_ifbody)?)\]|(?<Else>(?&_else))|(?<Begin>\[if:(?<If_Body>(?&_ifbody)?)\])(?<Core>(?&_core)|)(?<End>\[endif\])|(?<Error>(?&_keyword)))(?(DEFINE)(?<_ifbody>(?>[^\]])+)(?<_core>(?>(?<_content>(?>(?!(?&_keyword)).)+)|(?(<_else>)(?!))(?<_else>(?>\[else\]))|(?(<_else>)(?!))(?>\[elseif:(?&_ifbody)?\])|(?>\[if:(?&_ifbody)?\])(?:(?=.)(?&_core)|)\[endif\])+)(?<_keyword>(?>\[(?:(?:if|elseif):(?&_ifbody)?|endif|else)\])))

Formatted and tested:

 (?s)                               # Dot-all modifier

# =====================
# Outter Scope
# ---------------

(?:
(?<Content> # (1), Non-keyword CONTENT
(?&_content)
)
| # OR,
# --------------
\[ elseif: # ELSE IF
(?<ElseIf_Body> # (2), else if body
(?&_ifbody)?
)
\]
| # OR
# --------------
(?<Else> # (3), ELSE
(?&_else)
)
| # OR
# --------------
(?<Begin> # (4), IF
\[ if:
(?<If_Body> # (5), if body
(?&_ifbody)?
)
\]
)
(?<Core> # (6), The CORE
(?&_core)
|
)
(?<End> # (7)
\[ endif \] # END IF
)
| # OR
# --------------
(?<Error> # (8), Unbalanced If, ElseIf, Else, or End
(?&_keyword)
)
)

# =====================
# Subroutines
# ---------------

(?(DEFINE)

# __ If Body ----------------------
(?<_ifbody> # (9)
(?> [^\]] )+
)

# __ Core -------------------------
(?<_core> # (10)
(?>
#
# __ Content ( non-keywords )
(?<_content> # (11)
(?>
(?! (?&_keyword) )
.
)+
)
|
#
# __ Else
# Guard: Only 1 'else'
# allowed in this core !!

(?(<_else>)
(?!)
)
(?<_else> # (12)
(?> \[ else \] )
)
|
#
# __ ElseIf
# Guard: Not Else before ElseIf
# allowed in this core !!

(?(<_else>)
(?!)
)
(?>
\[ elseif:
(?&_ifbody)?
\]
)
|
#
# IF (block start)
(?>
\[ if:
(?&_ifbody)?
\]
)
# Recurse core
(?:
(?= . )
(?&_core)
|
)
# END IF (block end)
\[ endif \]
)+
)

# __ Keyword ----------------------
(?<_keyword> # (13)
(?>
\[
(?:
(?: if | elseif )
: (?&_ifbody)?
| endif
| else
)
\]
)
)
)

宿主语言伪代码

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

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

// ElseIf
if ( _matcher["ElseIf_Body"].matched == true )
{
// Check if we are not in a recursion
if ( nLevel <= 0 )
{
// Report error, this 'elseif' is outside an 'if/endif' block
// ( note - will only occur when nLevel == 0 )
print ("\n>> Error, 'elseif' not in block, body = " + _matcher["ElseIf_Body"].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 we have not hit an 'else' yet
// because all elseif's precede it.
// Print 'elseif'.
print ( "ElseIf: " );

// TBD - Body regex below
// Analyze the 'elseif' body.
// This is where it's body is parsed.
// Use body parsing (operations) regex on it.
string sElIfBody = _matcher["ElseIf_Body"].str() );

// If this 'elseif' body error will stop the process.
if ( bStopOnError == true )
bFoundError = true;
}
}


// 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/endif' block
// ( note - will only occur when nLevel == 0 )
print ("\n>> Error, 'else' not in block\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' within
// the relative scope of a single core.
// 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/endif' error will stop the process.
if ( bStopOnError == true )
bFoundError = true;
}

else

// If/EndIf block
if ( _matcher["Begin"].matched == true )
{
// Print 'If'
print ( "If:" );

// Analyze 'if body' for error and wish to return.

// TBD - Body regex below.
// Analyze the 'if' body.
// This is where it's body is parsed.
// Use body parsing (operations) regex on it.
string sIfBody = _matcher["If_Body"].str() );

// If this 'if' body error will stop the process.
if ( bStopOnError == true )
bFoundError = true;
else
{

//////////////////////////////
// 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 ( "EndIf" );
}
}

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" );

外核的输出样本匹配
请注意,当内核匹配时,会有更多的匹配。

 **  Grp 0               -  ( pos 0 , len 211 ) 
[if:(a+b-c/d*e)|(x-y)&!(z%3=0)]
output
[elseif:('b'+'atman'='batman')]
output2
[elseif:('b'+'atman'='batman')]
output3
[elseif:('b'+'atman'='batman')]
output4
[else]
output5
[endif]
** Grp 1 [Content] - NULL
** Grp 2 [ElseIf_Body] - NULL
** Grp 3 [Else] - NULL
** Grp 4 [Begin] - ( pos 0 , len 31 )
[if:(a+b-c/d*e)|(x-y)&!(z%3=0)]
** Grp 5 [If_Body] - ( pos 4 , len 26 )
(a+b-c/d*e)|(x-y)&!(z%3=0)
** Grp 6 [Core] - ( pos 31 , len 173 )

output
[elseif:('b'+'atman'='batman')]
output2
[elseif:('b'+'atman'='batman')]
output3
[elseif:('b'+'atman'='batman')]
output4
[else]
output5

** Grp 7 [End] - ( pos 204 , len 7 )
[endif]
** Grp 8 [Error] - NULL
** Grp 9 [_ifbody] - NULL
** Grp 10 [_core] - NULL
** Grp 11 [_content] - NULL
** Grp 12 [_else] - NULL
** Grp 13 [_keyword] - NULL

-----------------------------

** Grp 0 - ( pos 211 , len 4 )



** Grp 1 [Content] - ( pos 211 , len 4 )



** Grp 2 [ElseIf_Body] - NULL
** Grp 3 [Else] - NULL
** Grp 4 [Begin] - NULL
** Grp 5 [If_Body] - NULL
** Grp 6 [Core] - NULL
** Grp 7 [End] - NULL
** Grp 8 [Error] - NULL
** Grp 9 [_ifbody] - NULL
** Grp 10 [_core] - NULL
** Grp 11 [_content] - NULL
** Grp 12 [_else] - NULL
** Grp 13 [_keyword] - NULL

-----------------------------

** Grp 0 - ( pos 215 , len 74 )
[if:(a+b-c/d*e)|(x-y)&!(z%3=0)]
output6
[else]
output7
[endif]
** Grp 1 [Content] - NULL
** Grp 2 [ElseIf_Body] - NULL
** Grp 3 [Else] - NULL
** Grp 4 [Begin] - ( pos 215 , len 31 )
[if:(a+b-c/d*e)|(x-y)&!(z%3=0)]
** Grp 5 [If_Body] - ( pos 219 , len 26 )
(a+b-c/d*e)|(x-y)&!(z%3=0)
** Grp 6 [Core] - ( pos 246 , len 36 )

output6
[else]
output7

** Grp 7 [End] - ( pos 282 , len 7 )
[endif]
** Grp 8 [Error] - NULL
** Grp 9 [_ifbody] - NULL
** Grp 10 [_core] - NULL
** Grp 11 [_content] - NULL
** Grp 12 [_else] - NULL
** Grp 13 [_keyword] - NULL

这是 If/ElseIf Body 正则表达式

原始

(?|((?:\s*[^\^=<>+\-%/!&|()\[\]*\s]\s*)+)([\^+\-%/*=]+)(?=\s*[^\^=<>+\-%/!&|()\[\]*\s])|\G(?!^)(?<=[\^+\-%/*=])((?:\s*[^\^=<>+\-%/!&|()\[\]*\s]\s*)+)())

弦乐

'~(?|((?:\s*[^\^=<>+\-%/!&|()\[\]*\s]\s*)+)([\^+\-%/*=]+)(?=\s*[^\^=<>+\-%/!&|()\[\]*\s])|\G(?!^)(?<=[\^+\-%/*=])((?:\s*[^\^=<>+\-%/!&|()\[\]*\s]\s*)+)())~'

展开

 (?|                                           # Branch Reset
( # (1 start), Operand
(?: \s* [^\^=<>+\-%/!&|()\[\]*\s] \s* )+
) # (1 end)
( [\^+\-%/*=]+ ) # (2), Forward Operator
(?= \s* [^\^=<>+\-%/!&|()\[\]*\s] )
|
\G
(?! ^ )
(?<= [\^+\-%/*=] )
( # (1 start), Last Operand
(?: \s* [^\^=<>+\-%/!&|()\[\]*\s] \s* )+
) # (1 end)
( ) # (2), Last-Empty Forward Operator
)

这是它的运作方式:
假定构造非常简单。
这只会解析数学操作数/运算符。
它不会解析任何封闭的括号 block ,也不会解析任何逻辑或数学
之间的运营商。

如果需要,提前解析任何括号 block ,即 \( [^)*\)
相似的。或者拆分逻辑运算符,如 |

主体正则表达式使用分支重置来获取操作数/运算符序列。
它总是匹配两个东西。
第 1 组包含操作数,第 2 组包含运算符。

如果第 2 组为空,则第 1 组是序列中的最后操作数。

有效的运算符是 ^ + - %/* =
包含等号 = 是因为它分隔了操作集群
并且可以只记为分离。

关于这个主体正则表达式的结论是它非常简单并且
只适合简单使用。任何更复杂的事情都涉及
这不是要走的路。

输入/输出示例 1:

(a+b-c/d*e)

** Grp 1 - ( pos 1 , len 1 )
a
** Grp 2 - ( pos 2 , len 1 )
+
------------
** Grp 1 - ( pos 3 , len 1 )
b
** Grp 2 - ( pos 4 , len 1 )
-
------------
** Grp 1 - ( pos 5 , len 1 )
c
** Grp 2 - ( pos 6 , len 1 )
/
------------
** Grp 1 - ( pos 7 , len 1 )
d
** Grp 2 - ( pos 8 , len 1 )
*
------------
** Grp 1 - ( pos 9 , len 1 )
e
** Grp 2 - ( pos 10 , len 0 ) EMPTY

输入/输出示例 2:

('b'+'atman'='batman')

** Grp 1 - ( pos 1 , len 3 )
'b'
** Grp 2 - ( pos 4 , len 1 )
+
------------
** Grp 1 - ( pos 5 , len 7 )
'atman'
** Grp 2 - ( pos 12 , len 1 )
=
------------
** Grp 1 - ( pos 13 , len 8 )
'batman'
** Grp 2 - ( pos 21 , len 0 ) EMPTY

关于php - 正则表达式 - 获取元素以呈现 if 语句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37772338/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com