Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

RegEx Question 1

Status
Not open for further replies.

septemberlogic

Technical User
Feb 10, 2007
15
US
Hi,

For the following string,

$str = "Vin[i,j] + Vout[i,j] + Uin[i,j] + Uout[i,j]";

I want to replace the i's and j's in the square brackets with actually indices. So something like "$str =~ s/i/2/g", except for that changes the variable name as well (Vin becomes V2n). So my questions is, how do I limit my find-and-replace with in the square brackets?

Thanks in advance!
 
one simple minded way:

$str =~ s/i,/2,/g;

and for j

$str =~ s/j\]/2]/g;

------------------------------------------
- Kevin, perl coder unexceptional! [wiggle]
 
Thanks Kevin. Even though the example I gave was two dimensional, there are potentially multi-dimensional equations, such as Vin[i, j, k]. Is there a more general way of searching and replacing within the square brackets? Thanks!
 
continuing with simple mindedness:

Code:
$str = "Vin[i,j] + Vout[i,j,k] + Uin[i,j,k] + Uout[i,j]";

$str =~ s/i([,\]])/2$1/g;
$str =~ s/j([,\]])/1$1/g;
$str =~ s/k([,\]])/3$1/g;
print $str;


how are you defining values for i,j,k etc in your script?

------------------------------------------
- Kevin, perl coder unexceptional! [wiggle]
 
Hi Kevin,

The ijk's are going to be loop variables. So it's like writing out the summation series in loops. Anyway I've decided to do it a more complicated way, so that I can make sure the substitution takes place even if there're random whitespace characters in the square brackets. Here's my long-winded code:
$temp = $original;
while ($original =~ m/(\[.*?\])/g) {
$sub = $1;
$s = $1;
$sub = substr($sub, 1, length($sub)-2);
$s =~ s/$index/$number/g;
$s = substr($s, 1, length($s)-2);
$temp =~ s/$sub/$s/;
}
print $temp;

 
Hi SeptemberLogic,

Just do this in multiple steps, by using the 'e' modifier to execute code within your regex replacement. Also create an intermediate data structure to make your life a little easier.

Code:
my %currentIndexes = (i => $i, j => $j, k => $k);
my $temp = $original;
$temp =~ s{(\[.*?\])}{
	my $indexes = $1;
	$indexes =~ s/(\w+)/$currentIndexes{$1}/g;
	$indexes;
}eg;
print $temp;

You could even add error checking to the embedded regex to verify that the index that it found actually exists.

- Miller
 
Miller,

Thanks for your reply. I can't say I fully understand what's going on yet. I'm a quasi-programmer who only codes if I have a project that requires some sort of automated file/text manipulation (and that's very rare). I will read up on what exactly every line in your code does.

Thanks again!

 
no problem to compensate for random white spaces even with my simple minded approach:

Code:
my $str = 'Vin[i ,j ] + Vout[ i, j, k] + Uin[i ,j, k] + Uout[ i, j ]';
my %i = (i => 1, j => 2, k => 3);
$str =~ s/(\w)\s*([,\]])/$i{$1}$2/g;
print $str;

Millers suggestion is better in that it targets the [i,j] part of the pattern so could be more accurate it circumstances dictated. Mine may only have the benefit of being easier to understand.

------------------------------------------
- Kevin, perl coder unexceptional! [wiggle]
 
Status
Not open for further replies.

Similar threads

Part and Inventory Search

Sponsor

Back
Top