我正在尝试匹配不同的逻辑表达式,例如:“$a and $b
”使用Perl正则表达式,这是我的代码:
$input =~ /^(.*)\s(and|or|==|<|>|>=|<=)\s(.*)$/ {
$arg1=$1;
$arg2=$3;
$opt=$2;
}
我的目的是获得:
$arg1="$ARGV[0]=~/\w{4}/"
$arg2="$num_arg==1"
$opt ="and"
我想获得或表达式中匹配的确切值。我不希望对所有情况做同样的事情来逐个匹配,并对操作符进行硬编码。
有谁知道如何解决这个问题?
答案 0 :(得分:1)
此代码适用于我:
$input = '$ARGV[0]=~/\w{4}/ and $num_arg==1';
if ($input=~/^(.*)\s(and|or|==|<|>|>=|<=)\s(.*)$/) {
$arg1=$1;
$arg2=$3;
$opt=$2;
print "$arg1\n$arg2\n$opt\n";
}
答案 1 :(得分:1)
您需要一个能够揭示逻辑表达式结构的小解析器。那是因为你可能在一个术语中有另一个表达式。您可以使用perl来使用Marpa::R2包来测试您的语法。
作为第一次尝试,我会写:
<expression> ::= <term> | <expression> <binary-op> <term>
<term> ::= <factor> <binary-op> <factor> | <unary-op><factor>
<factor> ::= <id>
<binary-op> ::= (and|or|==|<|>|>=|<=)
<unary-op> ::= (not | ! )
有一点可以肯定,你不能完全使用正则表达式来描述逻辑表达式的语法,它总是缺少一些有效的案例。
用于验证的Perl代码
use Modern::Perl;
use Marpa::R2;
my $dsl = <<'END_OF_DSL';
:default ::= action => [name,values]
lexeme default = latm => 1
Expression ::= Term
| Expression BinaryOP Term
Term ::= Factor BinaryOP Factor
| UnaryOP Factor
Factor ::= ID
ID ~ [\w]+
BinaryOP ~ 'and' | 'or' | '==' | '<' | '>' | '>=' | '<='
UnaryOP ~ 'not' | '!'
:discard ~ whitespace
whitespace ~ [\s]+
END_OF_DSL
# your input
my $input = 'a and b or !c';
# your parser
my $grammar = Marpa::R2::Scanless::G->new( { source => \$dsl } );
# process input
my $recce = Marpa::R2::Scanless::R->new(
{ grammar => $grammar, semantics_package => 'My_Actions' } );
my $length_read = $recce->read( \$input );
die "Read ended after $length_read of ", length $input, " characters"
if $length_read != length $input;