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