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 SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Multiple Replacement within a loop help. 2

Status
Not open for further replies.

DunLudjin

Technical User
Jun 17, 2009
11
0
0
US
I'm using windows and taking the paths into a file. An example path is:

M:\O&M Manuals and Databooks\Manual by Job No\Job 9200s\9216\3.0-Manufacturing\3.8-Welding-MTRs\3.8.1-Piping\3.8.1.3-Video-Borescope\3.11.1.3.3-Blowdown-Piping\9216BLDN Weld #10, Detail B.swf

A number of these are in the @titles array.

I've been trying to feed it into a hash with the following code

foreach (@titles) {
my $i=$_;
$i =~ /(.*)?\\(?:.*)?-(.*?)?-(.*)?\\(.*?\#(\d*).*?)?.swf$/i; #used to parse the path
my $who=$4;
my $swffilename = $4;
$swffilename =~ tr{/\.\,\&\# \\s\.}{-};
$swffilename =~ s/--/-/g; # when this is commented out, it works fine but leaves the --
my $part= "$4: num=$5;piping=$2;swffile=$swffilename.swf;jpgfile=$swffilename.jpg";
# $part =~ s/-{2,}/-/ig;
print "$part\n";
my $key;
my $value;
my $rec={};
$titletest{$who} = $rec;
for my $ field (split(/;/,$part)){
($key,$value)= split /=/, $field;
$rec->{$key}=$value;
}
}


Can someone explain why the search and replace causes this to fail?

Thanks,

Shawn
 
I don't see what you are hoping to achieve with this:

my $rec={};
 
There are a lot of variables manipulated whenever you use the =~ function (or whatever it is to be called). Your first usage (the one that parses your path) sets various $1, $2, ... vars (among others). Your second usage =~ s/--/-/g; is resetting them. In this case since you're not using ()'s, the $1, .. $n are set to nulls.

FWIW - A common way I use to work with this would be:
Code:
@rc = ($i =~ /(.*)?\\(?:.*)?-(.*?)?-(.*)?\\(.*?\#(\d*).*?)?.swf$/i);
Now @rc will hold all of the values associated with $1, ... $n but will not change on the next usage of =~
 
You gave the path that you're starting with, after all the data munging (substitutions / splits / etc.) what are you expecting to end up with?

I've been trying to feed it into a hash with the following code
More specifically, what do you want the data to look like in your hash? There might be an easier way to get there.
 
I'm inclined to agree w/ rharsh. Instead of this line:
Code:
my $part = "bla;bla;bla" ;
Followed by a loop breaking the values up, a more direct path may be to just assign your hash directly as in:
Code:
$rec->{'who'} = $who ;
$rec->{'num'} = $5 ;
$rec->{'piping'} = $2 ;
# etc

Note that your usage of $rec can be handy when passing hash references to subroutine calls, but be mindful of downstream syntax. Consider the following:
Code:
$hash_var{'key'} = 'value1' ;
print ">$hash_var{'key'}<\n";
$hash_ref = \%hash_var ;
$hash_ref->{'key'} = 'value2' ;
print ">$hash_var{'key'}<\n"; # will print value2
# and another way is
print ">${$hash_ref}{'key'}<\n"; # will print value2
 
... If I may add:
My usage of arrows ><'s in the print statements above are an old debug habit of making sure what is getting printed where. It helps me see if spaces are showing up at the ends of strings and/or if there is anything printing at all. The arrows otherwise do not serve a purpose.
 
How about something like:
Code:
$i =~ /(.*)?\\(?:.*)?-(.*?)?-(.*)?\\(.*?\#(\d*).*?)?.swf$/i;  #used to parse the path
my $who=$4;
my $swffilename = $4;
my $part = "$4: num=$5;piping=$2;swffile=";
$swffilename =~ s![/.,&#\s]+!-!g;
$part .= "$swffilename.swf;jpgfile=$swffilename.jpg";
print "$part\n";

foreach my $field (split /;/, $part){
	my ($key,$value)= split /=/, $field;
	$titletest{$who}->{$key} = $value;
}
 
PinkeyNBrain - are you sure about the $1, $2 getting reset? Having lost a similar argument to this a couple of years back on this forum, I'm pretty sure they don't get reset unless you run another regex that (a) has capturing parentheses and (b) positively matches something.

There is some justification for this behaviour on the perldoc, but I've always felt it was a bit flaky.

Steve

[small]"Every program can be reduced by one instruction, and every program has at least one bug. Therefore, any program can be reduced to one instruction which doesn't work." (Object::perlDesignPatterns)[/small]
 
Code:
$avar = "a random string";
$avar =~ /.*(dom).*/;
print ">$1<\n";
$avar =~ /.*dom.*/;
print ">$1<\n";
 
Now that I'm thinking about it - I'm using ActiveState perl on WinXP. While they should be the same - will try the above prog on a SuSE box just for a cross check.
 
Can't argue with that -
Code:
>dom<
><
My bad.

Steve

[small]"Every program can be reduced by one instruction, and every program has at least one bug. Therefore, any program can be reduced to one instruction which doesn't work." (Object::perlDesignPatterns)[/small]
 
perlvars said:
$<digits> ($1, $2, ...)
Contains the subpattern from the corresponding set of capturing parentheses from the [red]last successful pattern match[/red], not counting patterns matched in nested blocks that have been exited already. (Mnemonic: like \digits.) These variables are all read-only and dynamically scoped to the current BLOCK.
However perlre doesn't use those words...

Steve

[small]"Every program can be reduced by one instruction, and every program has at least one bug. Therefore, any program can be reduced to one instruction which doesn't work." (Object::perlDesignPatterns)[/small]
 
The more pertinent test of the "last successful" is this instead.
[tt]
$avar = "a random string";
$avar =~ /.*(dom).*/;
print ">$1<\n";
$avar =~ /.*dxm.*/; #no match
print ">$1<\n";
[/tt]
 
Vindicated! Have a star, tsuji. I knew my brain hadn't gone completely to mush just yet...

Steve

[small]"Every program can be reduced by one instruction, and every program has at least one bug. Therefore, any program can be reduced to one instruction which doesn't work." (Object::perlDesignPatterns)[/small]
 
Touche` tsuji. Nonetheless the original question was asking what is going on with the $<digit> vars. While this may not be the popular view, I advocate being very cautious when using built in vars. Perl can create some clever code in tiny amount of space, but it can lead to long debugging sessions when your code starts to reach several thousand lines or more.
 
You've something to advocate; I have none.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top