如何在perl正则表达式中提取哪个a或b匹配/(a | b)/

时间:2016-09-05 11:04:00

标签: regex perl

我正在尝试匹配不同的逻辑表达式,例如:“$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"

我想获得或表达式中匹配的确切值。我不希望对所有情况做同样的事情来逐个匹配,并对操作符进行硬编码。

有谁知道如何解决这个问题?

2 个答案:

答案 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;