2015-01-17 127 views
1

以下代碼逐行讀取defines.c文件並將所有"#define"指令存儲在散列中(定義了名稱及其替換文本)。然後,如果在連續行上查找使用情況,則將它們替換它們。Perl替換:無法用變量perl替換正則表達式

如果使用"#define"指令,那麼替換時出現問題。它正確地將所有#defines存儲在散列中。

我是一個perl和正則表達式的初學者,無法指出愚蠢的事情,爲什麼它不工作。
任何幫助?

#!/usr/bin/perl -w 

use strict; 
my %definesHash; 

open(FILE, "defines.c") || die "Cannot open $!\n"; 
open(OUT, ">defines.i") || die "Cannot open $!\n"; 


while (<FILE>) 
{ 
my $line = $_; 
if ($line =~ /#define\s+/) 
{ 
    $line =~ s/#define\s+//g; 
    if ($line =~ /\b([\w]+)\b\s+/) 
    { 
    my $define = $1; 
    $line =~ s/\b[\w]+\b\s+//; 
    $definesHash{$define} = ""; 
    if($line =~ /\s*(.*)\s*/) 
    { 
     $definesHash{$define} = $1; 
    } 
    } 
    print OUT $_; 
} 
else 
{ 
    my($def, $replace); 
    while (($def, $replace) = each(%definesHash)) 
    { 
    print " $def => $replace \n"; 
    if ($line =~ /$def/) 
    { 
     $line =~ s/$def/$replace/g; #****** Some Problem Here, But What? ******** 
    } 
    } 
    print OUT $line; 
} 
} 

close(FILE); 
close(OUT); 

defines.c

#include <stdio.h> 

#define VALUE 10 
#define PLACE (20 + 0) 
#define NUM (VALUE + 10) 
int main() 
{ 
    int num; 
    num = NUM + 25 + NUM + PLACE; 
    return 0; 
} 

Expected Output: **defines.i**

#include <stdio.h> 

#define VALUE 10 
#define PLACE (20 + 0) 
#define NUM (VALUE + 10) 
int main() 
{ 
    int num; 
    num = (10 + 10) + 25 + (10 + 10) + (20 + 0); 
    // or 
    num = (VALUE + 10) + 25 + (VALUE + 10) + (20 + 0); 
    return 0; 
} 

我知道這個問題是在替代正如我指出的評論。在替換之後,我可以看到原始行變成亂碼,而散列中的內容似乎是正確的。
它與替代變量的用法?

+0

你可以給出例子和預期的輸出。 – Sobrique

+0

你的腳本適合我。我得到了預期的結果。 – Toto

+0

您的程序提供了預期的輸出並正常工作。你有什麼問題?你無法獲得預期的產出? – Praveen

回答

1

它看起來像你的腳本取決於散列的順序(或者說,無序)。

#define VALUE 10 
#define NUM (VALUE + 10) 

的定義沒有更新,因爲替換髮生在else - 所以只能更換上線必有#define

但是,在執行,不管以何種順序each給你替換 - 所以它可能是試圖取代VALUE,並且然後試圖取代NUM

我可能會執行初始置換中的每個定義,因爲他們來了,這樣的事情:

#!/usr/bin/perl 

use warnings; 
use strict; 
my %definesHash; 

open(my $fh_in, '<', "defines.c") || die "Cannot open $!\n"; 
open(my $fh_out, '>', "defines.i") || die "Cannot open $!\n"; 

while (<$fh_in>) { 
    if (/^#define\s+(\w+)\s+(.*)\s*$/) { 
     my ($define, $replacement) = ($1, $2); 
     # perform existing replacements on 
     # the current $replacement 
     while (my ($def, $replace) = each %definesHash) { 
      $replacement =~ s/$def/\Q$replace/g; 
     } 
     $definesHash{$define} = $replacement; 
    } 
    else { 
     while (my ($def, $replace) = each(%definesHash)) { 
      print " $def => $replace \n"; 
      s/$def/$replace/g; 
     } 
    } 

    print $fh_out $_; 
} 

close($fh_in); 
close($fh_out); 

或者,它可能是轉義正則表達式元字符,由\Q這裏逃脫。

+0

我知道散列的非排序。這完全不會產生預期的輸出。我能夠解決這個問題。順便說一句,感謝您的簡要代碼。 – user3144089

+0

原來是什麼問題? –

+0

我已經把它放在問題的評論中。請看那裏。我認爲這個問題現在沒有意義,如果你不介意的話,我想刪除這個問題。 – user3144089