【发布时间】:2014-04-16 14:49:56
【问题描述】:
我想验证一个字符串,它包含一个类似的表达式
isFun && ( isHelpful || isUseful )
这些表达式可以包含操作数、二元运算符和一元运算符:
my $unary_operator = qr/(?:\+|\-|!|not)/;
my $binary_operator = qr/(?:<|>|<=|>=|==|\!\=|<=>|\~\~|\&|\||\^|\&\&|\|\||lt|gt|le|ge|and|or|xor|eq|ne|cmp)/i;
my $operand = qr/[a-z0-9_]+/i;
它们有点类似于您从 perl 的条件模式中所知道的(例如在 if 语句中)。括号必须平衡,一元运算符只能连续使用一次。
我想找到一个与 perl 兼容的正则表达式,它确保有一个有效的逻辑/数学表达式,其中只使用给定的运算符,并且操作数与$operand 给出的正则表达式匹配。通过递归,这在 perl 中是可能的。该语句采用中缀表示法。
我目前的解决方案是解析一棵树并执行一些迭代,但我想将此算法压缩为单个正则表达式。
对于我的第一次尝试(我仍然排除了所有详细操作数),我使用了
my $re =
qr{
( # 1
( # 2 operands ...
$operand
)
|
( # 3 unary operators with recursion for operand
(?:$unary_operator(?!\s*$unary_operator)\s*(?1))
)
|
( # 4 balance brackets
\(
\s*(?1)\s*
\)
)
|
( # 5 binary operators with recursion for each operand
(?1)\s*$binary_operator\s*(?1)
)
)
}x;
...最终以无限递归结束。我认为递归可能是由于使用括号 5 中的第一个 (?1) 引起的。
有人有可行的解决方案吗?
【问题讨论】: