2015-01-17 4 views
1

Следующий код считывает файл define.c по очереди и сохраняет все директивы "#define" в хеше (с именем и заменяющим текстом). Затем он заменяет их, если поиск найден на последовательных строках.Perl Substitute: Невозможно заменить переменные perl regex

У меня есть проблема с заменой, если используется директива "#define". Он сохраняет все #defines правильно в хеше.

Я новичок в perl и regex и не могу указать на глупую вещь о том, почему она не работает.
Любая помощь?

#!/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

Я знал о неуказании хеша. Это полностью не дает ожидаемого результата. Я смог это исправить. BTW благодарит за компактный код. – user3144089

+0

Что оказалось проблемой? –

+0

Я поставил его в комментариях по вопросу. Пожалуйста, смотрите там. Я думаю, что сейчас вопрос спорный и хотел бы удалить его, если вы не возражаете. – user3144089

Смежные вопросы