2013-02-06 40 views
0

給定的文本是「C」式結構 -字符串替換不會在Perl工作

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; 
    } 

取代沒有工作和$線仍然是所有評估不變元素數。

+2

$ 1包含了都由S /// –

+0

其他的解決方案可能是更明智的interpeted特殊字符(*,+),但如果你需要匹配一個字面在未來的正則表達式中,您應該看看'\ Q'轉義或'quotemeta'。 – hobbs

回答

0

試試這個方法:$line =~ s/.*?\[(.*?)\]/$1/ge

+0

這將取代整條線。 – Toto

+0

我的錯,沒有測試 – pstr

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運算符,而不是指數運算符**

0

看起來像米格爾是正確的:

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]; 

所以你看,你還需要改變的特殊字符「的力量。」 但我認爲這指出你在正確的方向。

0

使用quotemeta來淨化你的替換字符串:

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