(Ovid) Re: REGEX: muliple search and replace
by Ovid (Cardinal) on Nov 14, 2000 at 09:25 UTC
|
While I am well-known as a fan of regexes, I wouldn't recommend them here. Since you're already using a template, why not go whole hog and take advantage of the features of HTML::Template? Take the following template:
<HTML>
<HEAD><TITLE>Test Template</TITLE>
<BODY>
<H1><TMPL_VAR NAME=something></h1>
<!--<TMPL_VAR NAME=var1>-->
This is a lame Web page
<!--<TMPL_VAR NAME=var2>-->
</BODY>
</HTML>
Use the following CGI script:
#!c:\perl\bin\perl.exe -wT
use strict;
use HTML::Template;
use CGI qw/:standard/;
# open the html template
my $template = HTML::Template->new(filename => 'template.tmpl');
# fill in some parameters
$template->param(
something => "Test",
var1 => "Some Comment",
var2 => "Another comment"
);
print header,
$template->output;
You'll see that the HTML comments have been filled in quite nicely. Read the documentation of this module and you'll see how very useful it can be.
Cheers,
Ovid
Join the Perlmonks Setiathome Group or just click on the the link and check out our stats. | [reply] [d/l] [select] |
RE (tilly) 1: REGEX: muliple search and replace
by tilly (Archbishop) on Nov 14, 2000 at 09:24 UTC
|
Well first of all I would suggest that you look at some of
the standard template answers such as Template::Toolkit
rather than rolling your own.
But for your specific question, if %replace has your
translation of key to value then you can do this:
my $match = join "|", map {quotemeta($_)} keys %replace;
$str = s/<--($match)-->/$replace{$1}/g;
| [reply] [d/l] |
|
|
Thank you very much,
This was just what I was after, so simple, now that I know it, it is these sort of tricks I look out for on this site in an effort to eventually be able come up with them myself.
Please allow me to defend my choice of not using a module for this, apart from a lot of rework of both my script and templates. When I use a template to achieve a result, I've learnt how to use a template, but when I do it myself I better my understanding and knowledge of perl.
Most of my projects are web interfaces and cgi bits and pieces so my use for perl at the moment is narrow, so I am always looking for new methods and techniques, and for that THIS Monastery is a God send <Pun Definitely intended>
Thanks to all who responded to my question
| [reply] |
|
|
Please allow me to defend my choice of not using a module for this...
There is absolutely nothing wrong with "rolling your own", so long as you understand why you are doing it. After all, how do you think the modules on CPAN were created? While many were for new functions, others were expanding upon previously created functionality or approaching the problem from an entirely different direction (the plethora of mail modules comes to mind).
However, if you happen to be working for a company, you are doing them a disservice. If you are new to Perl, as your post suggests, then you won't write Perl code that is as stable and well-thought out as most of the modules out there. Your company has to deal with your substandard code and is probably not getting best value for what they are paying you. As a matter of simple ethics, I would recommend not "rolling your own" in a business environment without very compelling reasons.
When I use a template to achieve a result, I've learnt how to use a template, but when I do it myself I better my understanding and knowledge of perl.
The above comment suggests to me that you would benefit greatly from using more modules and templates. If you don't use them, you can't appreciate how your knowledge of Perl increases through said use. Further, without those modules, Perl wouldn't be as popular as it is and you probably wouldn't be coding in it.
Much of being a good Perl programmer is being a good programmer. Learning the benefits of code reuse and modularization aren't specific to Perl, but you must understand these issues if you want to be a serious programmer. Read through the white paper for Template::Toolkit. In just fifteen minutes to half an hour of reading, you will have learned more about Web site creation and maintenance than I learned in my first six months of "doing it by hand." It covers the benefits of code reuse and modularity from a CGI perspective. Just some of the topics covered:
- Control over design aspects
- Cross-site consistency
- Separation of code and presentation
- Reusability
- Maintainability and portability
If you really want to be writing CGI programs, those are critical issues. By understanding them and getting them out of the way, you can focus on Perl.
Don't get me wrong, I meant what I said. There is NOTHING wrong with writing your own version of modules that are already out there if you are doing this to further your understanding. I have personally written a couple of CGI parsing routines in order to better understand the CGI protocol. However, if you are inexperienced with Perl and you arte doing this for an employer (as your post and home node hint at), you are doing them a disservice. That, in my opinion, is unethical.
Cheers,
Ovid
Join the Perlmonks Setiathome Group or just click on the the link and check out our stats.
| [reply] |
|
|
RE: REGEX: muliple search and replace
by mitd (Curate) on Nov 14, 2000 at 09:50 UTC
|
There are many different solutions out there (read CPAN). But
for straight variable replace. I like this litte
fast solution. There are certainly some more 'complete'
solutions, but none matches this on for speed.
# Just hand it a hash with keys=var name, value=replace value.
# template encoding scheme is %%\s*varname\*%%
package Template;
use strict;
require 5.004;
use Carp;
sub new {
my $proto = shift;
my $class = ref($proto) || $proto;
my $path = shift;
open(F,"<$path") or croak "Cannot open $path for read: $!";
my $template = do { local $/; scalar <F> };
my $self = { template => $template };
bless $self, $class;
return $self;
}
sub spit {
my $self = shift;
my $data = shift;
my $template = $self->{template};
foreach my $field (keys %$data) {
my $subber = $data->{$field} || '';
$template =~ s/%%\s*$field\s*%%/$subber/g;
}
# now nuke all unfilled variables
$template =~ s/%%\s*[A-Za-z0-9_]+\s*%%//g;
return $template;
}
1;
code orginally inspired by J. Feinberg NYC who may or
may not be a member monk
mitd-Made in the Dark
'My favourite colour appears to be grey.' | [reply] [d/l] |
RE: REGEX: muliple search and replace
by a (Friar) on Nov 14, 2000 at 09:03 UTC
|
I'm betting there's some cool way of doing:
s/<!--var(\d+)-->/$var_vals{$1}/eg
where %var_vals (probably an array'd work but ...) is filled
w/ your varX's values ahead of time. I'm (blush) not sure,
or rather, doubt the /e is needed (if it *is* the 'execute the
RHS' flag - another blush. Where is my cheatbook?) but
that may be what you want.
a | [reply] [d/l] |
|
|
I'm not necessarily suggesting you do this, but if your variables are, say, $name, $email, etc. (i.e. they aren't in hashes) you can use symbolic references:
s/<!--var (\w+)-->/${"main::$1"}/eg
(so <!--var foo--> would be replaced by the contents of $foo.)
The only real advantage to punk music is that nobody can whistle it. | [reply] [d/l] [select] |
Re: REGEX: muliple search and replace
by Dr. Mu (Hermit) on Nov 14, 2000 at 10:52 UTC
|
Something like the following has worked well for me:
$ThisText = 'Lame webpage title.';
$ThatText = 'Lame webpage content.';
print <<END_OF_HTML;
Content-type: text/html
<HTML>
<HEAD>
<TITLE>$ThisText</TITLE>
</HEAD><BODY>
$ThatText
</BODY></HTML>
END_OF_HTML
The "here-document" multiline quote is interpolating, so
the strings are substituted correctly without resorting
to regular expressions. When the 'template' is large, I just put it, along with its
print statement in a separate file. I then slurp the
file into a variable and eval it. The variables still
scope and interporlate correctly. Now there may be security
ramifications for not doing it this way. If so, perhaps
someone can set me straight. | [reply] [d/l] |
Re: REGEX: muliple search and replace
by snax (Hermit) on Nov 14, 2000 at 13:38 UTC
|
| [reply] |
|
|
| [reply] |
Re: REGEX: muliple search and replace
by strredwolf (Chaplain) on Nov 14, 2000 at 19:21 UTC
|
As one Regexp, I would definetly go with:
s/<!---var(\d+)--->/$var{$1}/g;
This, of course, assinging $var{"1"} or whatever with the HTML you want. Sort of a poor-man's template, eh?
--
$Stalag99{"URL"}="http://stalag99.keenspace.com";
| [reply] [d/l] |
|
|
I use a variation on this that allows for both recursive expansion and late binding.
$vars{foo} = sub { int(rand(1) ? "bar" : "baz" };
$vars{bar} = "vi";
$vars{baz} = "emacs";
print expand_template("<!--foo--> rules!");
sub expand_template {
my $template = shift;
$template =~ s/<!--(\w+)-->/expand_template(expand_var($1))/ge;
return $template;
}
sub expand_var {
my $name = shift;
return "" if not exists $vars{$name};
return &{$vars{$name}}() if ref $vars{$name} eq "CODE";
return $vars{$name};
}
| [reply] |
Re: REGEX: muliple search and replace
by stephen (Priest) on Nov 14, 2000 at 21:54 UTC
|
The Text::Template module might help. Compiles the template into an anonymous subroutine, so it's only parsed/scanned once. Hoping to give it an upgrade this evening.
stephen
| [reply] |
RE: REGEX: muliple search and replace
by Anonymous Monk on Nov 15, 2000 at 03:11 UTC
|
BAH! You don't really want to do it this way at all. You should look into the Embperl modules, specifically HTML::Embperl It does exactly what you want to do. You have an HTML template file, but you actually embed Perl code in this file. HTML::Embperl then takes this file, and evaluates whatever Perl code is in the file, and generates an HTML file from this. The general format of this is to have a bunch of html, then with square brackets you embed Perl code that gets executed and the whatever value that block returns is inserted into the document. Just do a search for Embperl on www.perl.com and you will find it. It comes with good documentation so you should be able to figure out the specifics without too much heart burn.
Hope this helps,
Andrew Gibbs | [reply] |