Reputation: 3818
Given text is the 'C' style structure -
struct mystruct {
int a[100];
int b[10*10];
int c[10*5+(25*2)];
int d[10^2];
}
Read the text line by line and evaluate the number of elements in each array and re-declare arrays with element count.
Result should be printed as follows :-
struct mystruct {
int a[100];
int b[100];
int c[100];
int d[100];
}
Following string substitution doesn't work for me -
if ($line =~ m/.*?\[(.*?)\]/) {
$answer = eval ($1);
$line =~ s/$1/$answer/g;
}
The substitution did not work and the $line remained unchanged for all evaluated element count.
Upvotes: 0
Views: 182
Reputation: 2320
Use quotemeta
to sanitize your replacement string:
if ( $line =~ m/.*?\[(.*?)\]/ ) {
my $expr = quotemeta($1);
my $answer = eval ($1);
$line =~ s/$expr/$answer/;
}
Upvotes: 0
Reputation: 25
Looks like Miguel is right:
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";
}
This returns:
int a[100];
int b[100];
int c[100];
int d[8];
So you see you'll also need to alter the special character for "power of". But I think this points you in the right direction.
Upvotes: 0
Reputation: 67900
Do the evaluation directly in the substitution:
$line =~ s/(?<=\[) # assert a square bracket behind
([^]]*) # capture string of non-brackets
(?=\]) # assert square bracket after
/$1/eex; # double evaluate the variable
The double evaluation is necessary, as the first evaluation turns the variable into a string, and then the string is evaluated.
Although you will run into trouble with 10^2
, as ^
is the binary XOR operator, not the exponentiation operator **
.
Upvotes: 5