Re: regex substitution
by rchiav (Deacon) on Nov 05, 2001 at 06:33 UTC
|
closer to what you want..
$text =~ s/#([^#]+)#/$hash{$1}/g
Rich | [reply] [d/l] |
Re: regex substitution
by Masem (Monsignor) on Nov 05, 2001 at 06:33 UTC
|
Capture a match of the key itself, which you can then use in the replcement part of the regex to get your hash key:
$text =~ s/\#(\w+)\#/$hash{$1}/g;
-----------------------------------------------------
Dr. Michael K. Neylon - mneylon-pm@masemware.com
||
"You've left the lens cap of your mind on again, Pinky" - The Brain
"I can see my house from here!"
It's not what you know, but knowing how to find it if you don't know that's important
| [reply] [d/l] |
Re: regex substitution
by notsoevil (Pilgrim) on Nov 05, 2001 at 10:42 UTC
|
| [reply] |
Re: regex substitution
by dws (Chancellor) on Nov 05, 2001 at 08:35 UTC
|
But I can't for the life of me find an example that does this (substitutions within substitutions).
When doing substitutions like this, /e is your friend.
$text =~ s/\#\w+\#/$hash{$1}/eg;
/e forces the right-hand side of the s/// to be evaluated as a Perl expression, and the result substituted for whatever the left-hand side matched. The boundary between interpolation and substitution can seem pretty hazy, but it makes a bit more sense if you imagine that the regexp is "compiled" immediately before it is executed. At that point, $1 either doesn't have a value, or holds a value from a prior regexp. Neither is what you want.
Consult perlre for full details.
| [reply] [d/l] [select] |
|
|
Perhaps it shouldn't work without /e, but it does, at least with activestate perl 5.6.1. (obviously, you should use strict and warnings...)
#!perl
$_="this is a #fish#\n";
$a{"fish"}="test";
print;
s/#(\w+)#/$a{$1}/;
print;
this is a #fish#
this is a test
C:\perl -v
This is perl, v5.6.1 built for MSWin32-x86-multi-thread
(with 1 registered patch, see perl -V for more detail)
Copyright 1987-2001, Larry Wall
Binary build 626 provided by ActiveState Tool Corp. http://www.ActiveS
+tate.com
Built 01:31:15 May 2 2001
| [reply] [d/l] |
|
|
#!perl -w
use strict;
my %hashola = (fish => "test" );
sub f($){ return $hashola{shift @_}; }
my $rock = "this is a #fish#\n";
my $block = $rock;
print $rock;
$block =~ s/#(\w+)#/&f($1);/; # expands $1, doesn't call &f
print $block;
$block = $rock; # restoree
$block =~ s/#(\w+)#/$hashola{$1}/; # expands the variable
print $block;
$block = $rock; # restoree
$block =~ s/#(\w+)#/&f($1)/e; # calls the function
print $block;
$block = $rock; # restoree
$block =~ s/#(\w+)#/$hashola{$1}/e;
print $block;
$block = $rock; # restoree
__END__
F:\dev>perl f
this is a #fish#
this is a &f(fish);
this is a test
this is a test
this is a test
F:\dev>
Ok ok, from perlop (since s is an operator), I quote:
e Evaluate the right side as an expression.
Unless you escape $hashname{$1} like \$hashmane{$1}, the actual variable will be expanded independent of /e, as such is the nature of the s operator.
___crazyinsomniac_______________________________________
Disclaimer: Don't blame. It came from inside the void
perl -e "$q=$_;map({chr unpack qq;H*;,$_}split(q;;,q*H*));print;$q/$q;" | [reply] [d/l] [select] |
Re: regex substitution
by PetaMem (Priest) on Nov 05, 2001 at 14:16 UTC
|
Hi,
If you are into a heavy duty Text pre-processor, you could
use Text::Vpp.
It allows you even such fancy things like perl code being processed while you are
doing your preprocessing which will give you the possibility of doing
things like:
if($gender == 'f') {
Dear Mrs. $name,
} else {
Dear Mr. $name,
}
we would like to invite you...
We´re using this module for text-preprocessing of TeX-Files
for mass printing of letters to our customers. You cannot get
it much more flexible and powerfull than that.
Bye
PetaMem
| [reply] [d/l] |
Re: regex substitution
by tomazos (Deacon) on Nov 05, 2001 at 13:08 UTC
|
my $text = << 'end_of_test';
Your child <child> is invited to
come to our school. Your child's
teacher will be <teacher>, and the
class is held in <room>.";
end_of_test
my %hash = ('child' => 'mary',
'teacher' => 'mrs b',
'room' => '123');
print "Raw: $test\n";
$test =~
s[<(\w+)>]
[defined($hash{$1}) ? $hash{$1} : warn]ieg;
print "Processed: $test\n";
| [reply] [d/l] |
Re: regex substitution
by Dr. Mu (Hermit) on Nov 05, 2001 at 13:18 UTC
|
Umm, why not just use variable interpolation?
foreach (0..@ChildName - 1) {
my $text = "Your child $ChildName[$_] is invited to
come to our school. Your child's teacher will be
$TeacherName[$_], and the class is held in room
$RoomNo[$_].";
&PrintNotice($text) # or whatever...
}
| [reply] [d/l] |
|
|
Because this isn't within a script - I'm basically allowing users to create their own paragraph-like ouput of database rows. I wanted to have the combination of ease of use for non-savvy users, and ease of me translating the text into the right thing. I might convert to using <> instead of ##. ## is kinda useful because it's the way that some (like Cold Fusion) user-friendly systems use for variables.
| [reply] |
Re: regex substitution
by mitd (Curate) on Nov 05, 2001 at 13:28 UTC
|
| [reply] |
Re: regex substitution
by pike (Monk) on Nov 05, 2001 at 13:47 UTC
|
Actually, you were quite close to it, what you could use here is a Hash of Hashes to hold the data:
my $rhChildren = {
{'Peter'} => {
child_name => 'Peter',
teacher_name => 'Ms. Jones',
room_number => '503'
}
}; #add records as needed
my $text = "Your child #child_name# is invited to come to our school.
+Your child's teacher will be #teacher_name#, and the class is held in
+ room #room_number.";
foreach my $child (keys %$rhChildren) {
my $substText;
($substText = $text) =~ s/\#([^#]+)\#/$rhChildren->{$child}{$1}/g;
print "$substText\n";
}
OK, so there is a redundancy in using the child's name both as key and value in the hash, but it works and uses regexes, right? | [reply] [d/l] |
Re: regex substitution
by Anonymous Monk on Nov 05, 2001 at 16:22 UTC
|
you can group your expression to use it later in your substitution statement:
$text =~ s/\#(\w+)\#/$hash{$1}/g;
$1 refer to the first grouped expression in your regexp, so variable_name there. | [reply] |
Re: regex substitution
by Anonymous Monk on Nov 05, 2001 at 22:42 UTC
|
The previous examples either ignore greedy matching or attempt to to emulate it. I believe this is what you're looking for:
$text =~ s/#(\w+?)#/$hash{$1}/g;
--
pabs (who's too lazy to create an account)
pabs@pablotron.org
| [reply] [d/l] |
|
|
That would be a problem if \w included the octothorpe. It doesn't, so it's not a problem.
| [reply] [d/l] |
Re: regex substitution
by bigdan (Initiate) on Nov 06, 2001 at 09:30 UTC
|
Why waste time reinventing wheels that have already rolled
down this path many a time? Read the the perldocs for
Text::Template...it's a far more scalable and robust
solution than trying to develop your own template language!
-dK | [reply] |