- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我正在设计脚本并尝试在 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)\])))
(?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/
我正在用 yacc/bison 编写一个简单的计算器。 表达式的语法看起来有点像这样: expr : NUM | expr '+' expr { $$ = $1 + $3; } | expr '-'
我开始学习 lambda 表达式,并在以下情况下遇到了以下语句: interface MyNumber { double getValue(); } MyNumber number; nu
这两个 Linq 查询有什么区别: var result = ResultLists().Where( c=> c.code == "abc").FirstOrDefault(); // vs. va
如果我们查看 draft C++ standard 5.1.2 Lambda 表达式 段 2 说(强调我的 future ): The evaluation of a lambda-expressio
我使用的是 Mule 4.2.2 运行时、studio 7.5.1 和 Oracle JDK 1.8.0_251。 我在 java 代码中使用 Lambda 表达式,该表达式由 java Invoke
我是 XPath 的新手。我有网页的html源 http://london.craigslist.co.uk/com/1233708939.html 现在我想从上面的页面中提取以下数据 完整日期 电子
已关闭。这个问题是 off-topic 。目前不接受答案。 想要改进这个问题吗? Update the question所以它是on-topic用于堆栈溢出。 已关闭10 年前。 Improve th
我将如何编写一个 Cron 表达式以在每天上午 8 点和下午 3:30 触发?我了解如何创建每天触发一次的表达式,而不是在多个设定时间触发。提前致谢 最佳答案 你应该只使用两行。 0 8 * * *
这个问题已经有答案了: What do 3 dots next to a parameter type mean in Java? (9 个回答) varargs and the '...' argu
我是 python 新手,在阅读 BeautifulSoup 教程时,我不明白这个表达式“[x for x in titles if x.findChildren()][:-1]”我不明白?你能解释一
(?:) 这是一个有效的 ruby 正则表达式,谁能告诉我它是什么意思? 谢谢 最佳答案 正如其他人所说,它被用作正则表达式的非捕获语法,但是,它也是正则表达式之外的有效 ruby 语法。 在
这个问题在这里已经有了答案: Why does ++[[]][+[]]+[+[]] return the string "10"? (10 个答案) 关闭 8 年前。 谁能帮我处理这个 JavaSc
这个问题在这里已经有了答案: What is the "-->" operator in C++? (29 个答案) Java: Prefix/postfix of increment/decrem
这个问题在这里已经有了答案: List comprehension vs. lambda + filter (16 个答案) 关闭 10 个月前。 我不确定我是否需要 lambda 或其他东西。但是,
C 中的 assert() 函数工作原理对我来说就像一片黑暗的森林。根据这里的答案https://stackoverflow.com/a/1571360 ,您可以使用以下构造将自定义消息输出到您的断言
在this页,John Barnes 写道: If the conditional expression is the argument of a type conversion then effec
我必须创建一个调度程序,它必须每周从第一天上午 9 点到第二天晚上 11 点 59 分运行 2 天(星期四和星期五)。为此,我需要提供一个 cron 表达式。 0-0 0-0 9-23 ? * THU
我正在尝试编写一个 Linq 表达式来检查派生类中的属性,但该列表由来自基类的成员组成。下面的示例代码。以“var list”开头的 Process 方法的第二行无法编译,但我不确定应该使用什么语法来
此 sed 表达式将输入字符串转换为两行输出字符串。两条输出行中的每一行都由输入的子串组成。第一行需要转换成大写: s:random_stuff\(choice1\|choice2\){\([^}]*
我正在使用 Quartz.Net 在我的应用程序中安排我的工作。我只是想知道是否可以为以下场景构建 CRON 表达式: Every second between 2:15AM and 5:20AM 最
我是一名优秀的程序员,十分优秀!