Regex 逻辑条件/数学表达式验证
我想验证一个字符串,它包含一个表达式,如Regex 逻辑条件/数学表达式验证,regex,perl,Regex,Perl,我想验证一个字符串,它包含一个表达式,如 isFun && ( isHelpful || isUseful ) 这些表达式可以包含操作数、二元运算符和一元运算符: my $unary_operator = qr/(?:\+|\-|!|not)/; my $binary_operator = qr/(?:<|>|<=|>=|==|\!\=|<=>|\~\~|\&|\||\^|\&\&|\|\||lt|gt|le|ge|
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;
…以无限递归结束。我认为递归可能是使用括号5中的第一个(?1)引起的
是否有人提供了有效的解决方案?以下内容可用于验证您的表达式:
use strict;
use warnings;
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;
my $re =
qr{^
( # 1
\s*
(?> (?:$unary_operator \s*)* )
(?:
\b$operand\b
|
\( (?1) \)
)
(?:
\s*
$binary_operator
\s*
(?1)
)*
\s*
)
$}x;
while (<DATA>) {
chomp;
my ($expr, $status) = split "#", $_, 2;
if ($expr =~ $re) {
print "good $_\n";
} else {
print "bad $_\n";
}
}
__DATA__
isFun # Good
isFun && isHelpful # Good
isFun && isHelpful || isUseful # Good
isFun && ( isHelpful || isUseful ) # Good
isFun && ( isHelpful || (isUseful) ) # Good
isFun && ( isHelpful || (isUseful ) # Fail - Missing )
not (isFun && (isHelpful || (isBad && isDangerous))) # Good
isGenuine!isReal # Fail
!isGenuine isReal # Fail
嘿,米勒!这很接近,但对于
istrue,它将返回假阳性!以色列
和!isReal正版
。我认为这种情况会发生,因为ne
将操作符作为isGeniune
的一部分。为了解决这个问题,我在操作符集中用\bne\b
替换了ne
(以及所有其他详细的操作符),但是我更喜欢一个解决方案,可以处理上面问题中给出的操作符集。你认为这可能吗?是的,正则表达式的问题更多,但可以通过在操作数周围添加单词边界来解决:\b$operand\b
好的,操作数周围的单词边界显然比操作符周围的单词边界更有意义!谢谢大家!<代码>您的答案==(isAwesome&&isHelpful):D
use strict;
use warnings;
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;
my $re =
qr{^
( # 1
\s*
(?> (?:$unary_operator \s*)* )
(?:
\b$operand\b
|
\( (?1) \)
)
(?:
\s*
$binary_operator
\s*
(?1)
)*
\s*
)
$}x;
while (<DATA>) {
chomp;
my ($expr, $status) = split "#", $_, 2;
if ($expr =~ $re) {
print "good $_\n";
} else {
print "bad $_\n";
}
}
__DATA__
isFun # Good
isFun && isHelpful # Good
isFun && isHelpful || isUseful # Good
isFun && ( isHelpful || isUseful ) # Good
isFun && ( isHelpful || (isUseful) ) # Good
isFun && ( isHelpful || (isUseful ) # Fail - Missing )
not (isFun && (isHelpful || (isBad && isDangerous))) # Good
isGenuine!isReal # Fail
!isGenuine isReal # Fail
good isFun # Good
good isFun && isHelpful # Good
good isFun && isHelpful || isUseful # Good
good isFun && ( isHelpful || isUseful ) # Good
good isFun && ( isHelpful || (isUseful) ) # Good
bad isFun && ( isHelpful || (isUseful ) # Fail - Missing )
good not (isFun && (isHelpful || (isBad && isDangerous))) # Good
bad isGenuine!isReal # Fail
bad !isGenuine isReal # Fail