如何在两个字符之间提取字符串+重新进行?

时间:2009-11-11 14:38:39

标签: perl

我有一个字符串:

123 + FOO1[ccc + e_FOO1 + ddd + FOO2[b_FOO2]] = 123

现在,我需要检查FOO1是否与e_一起显示。也就是说,不可能出现这样的情况:

123 + FOO1[ccc + e_FOK1 ...]

我的简单问题是如何告诉Perl捕获FOO1字样?

我想在2个字符之间进行搜索:" ""["

然后检查" e_"之间的"[..]"之后是否正确写入。

我如何能够回收?

4 个答案:

答案 0 :(得分:2)

您需要为您的迷你语言编写解析器:请参阅Parse::RecDescentcalculator demo将是一个很好的起点。

#!/usr/bin/perl

use strict;
use warnings;

my ($expr) = @ARGV;

my @tokens = split //, $expr;

my ($word, $inside) = (q{}, 0);

for my $token (@tokens) {
    $token =~ /\A\w\z/ and do { $word .= $token; next };

    if ( $inside ) {
        if ( $word =~ /FOO1/ ) {
            $word eq 'e_FOO1'
                or die "No FOO1 w/o e_ prefix allowed!\n"
        }
    }
    else {
        $word !~ /FOO1/
            or die "No FOO1 allowed!\n";
    }

    $token eq '[' and ++$inside;
    $token eq ']' and --$inside;
    $word = '';
}
C:\Temp> t.pl "123 + MOO1[ccc + e_FOO1 + ddd + FOO2[b_FOO2]] = 123"
C:\Temp> t.pl "123 + FOO1[ccc + e_FOO1 + ddd + FOO2[b_FOO2]] = 123"
No FOO1 allowed!
C:\Temp> t.pl "123 + MOO1[ccc + FOO1 + ddd + FOO2[b_FOO2]] = 123"
No FOO1 w/o e_ prefix allowed!

另请参阅常见问题解答Can I use Perl regular expressions to match balanced text?

答案 1 :(得分:1)

根据你的一些评论,我将假设你的问题是“在'['和']'括号之间,确保任何'e_'符号都是'e_FOO'而不是别的...

(编辑:好吧,看起来您需要“FOO”关键字也出现在方括号前面。我会相应地修改正则表达式。)

if ($line =~ /
              ([A-Z]+)  # match a keyword in all caps, and save it for later
                        # (we can retrieve it with \1 or $1)
              \[        # match the first [
                [\]]*   # some number of any character that isn't ]
                e_      # a ha, here's our e_
                \1      # and here's our keyword that we matched earlier
                [\]]*   # some more of any character that isn't ]
              \]        # here's our closing ]
             /x)
{
     say "Good data";
}
else
{
     say "Bad data";
}

但是,请开始阅读perldoc perlre中的一些教程。

答案 2 :(得分:0)

如果你的情况比你描述的更复杂,那么这段代码就行不通了(例如,它没有做任何事情来确保你的左右括号相互平衡)。但是,代码确实说明了如何使用反向引用(请参阅下面的\1),这可能会让您走上正确的轨道。

use strict;
use warnings;

while (<DATA>){
    warn "Bad line: $_" unless / (\w+) \[ .* e_\1 .* \] /x;
}

__DATA__
123 + FOO1[ccc + e_FOO1 + ddd + FOO2[b_FOO2]] = 123
123 + FOO1[ccc + e_FOOx + ddd + FOO2[b_FOO2]] = 123

答案 3 :(得分:0)

因为您说“我需要确认FOO1是否遵循其括号内的”e_“字符串”,您只需要检查e_FOO1,对吗?不需要太复杂的正则表达式。

my $str="123 + FOO1[ccc + e_FOO1 + ddd + FOO2[b_FOO2]] = 123";
my $s = index($str,"[");
my $e = index($str,"]");
my $f = index($str,"e_FOO1");
if ( $f >=$s and $f <= $e ){
    print "found \n";
}