字符串替换在perl中不起作用

时间:2013-02-06 09:56:18

标签: regex perl

鉴于文本是'C'样式结构 -

    struct mystruct {
        int a[100];
        int b[10*10];
        int c[10*5+(25*2)];
        int d[10^2];
    }

逐行阅读文本并评估每个数组中的元素数量,并重新声明具有元素数的数组。

结果应按如下方式打印: -

    struct mystruct {
        int a[100];
        int b[100];
        int c[100];
        int d[100];
    }

以下字符串替换对我不起作用 -

    if ($line =~ m/.*?\[(.*?)\]/) {
        $answer = eval ($1);
        $line =~ s/$1/$answer/g;
    }

替换不起作用且所有评估元素计数的$ line保持不变。

4 个答案:

答案 0 :(得分:5)

直接在替换中进行评估:

$line =~ s/(?<=\[)   # assert a square bracket behind
           ([^]]*)   # capture string of non-brackets
           (?=\])    # assert square bracket after
          /$1/eex;   # double evaluate the variable

双重评估是必要的,因为第一个评估将变量转换为字符串,然后评估字符串。

虽然您会遇到10^2的问题,因为^是二进制XOR运算符,而不是指数运算符**

答案 1 :(得分:0)

尝试这种方式:$line =~ s/.*?\[(.*?)\]/$1/ge

答案 2 :(得分:0)

看起来Miguel是对的:

my $string =
q|int a[100];
int b[10*10];
int c[10*5+(25*2)];
int d[10^2];|;

foreach my $line (split(/\n/,$string)) {
        if ($line =~ m/\[([^\]]+)\]/) {
                my $equation = $1;
                my $val = eval($equation);
                # escape out the special characters.
                $equation =~ s/\*/\\\*/g;
                $equation =~ s/\,/\\\,/g;
                $equation =~ s/\+/\\\+/g;
                $equation =~ s/\)/\\\)/g;
                $equation =~ s/\(/\\\(/g;
                $equation =~ s/\^/\\\^/g;

                $line =~ s/\[$equation\]/\[$val\]/;
        }
        print "$line\n";
}

返回:

int a[100];
int b[100];
int c[100];
int d[8];

所以你看到你还需要改变“权力”的特殊性格。 但我认为这会指出你正确的方向。

答案 3 :(得分:0)

使用quotemeta清理替换字符串:

if ( $line =~ m/.*?\[(.*?)\]/ ) {
    my $expr = quotemeta($1);
    my $answer = eval ($1);
    $line =~ s/$expr/$answer/;
}