[H-GEN] A perl query
Jason Parker-Burlingham
jasonp at uq.net.au
Sun May 4 16:18:13 EDT 2003
[ Humbug *General* list - semi-serious discussions about Humbug and ]
[ Unix-related topics. Posts from non-subscribed addresses will vanish. ]
Conor Cunningham <cunningtek at optusnet.com.au> writes:
I'm sorry, this is wrong:
> $line = s/SEARCH/REPLACE/gi;
$line holds a certain amount of input from <LOGFILE> (as defined by
the current value of $/; it will default to one line). But assigning
it the value of a regular expression substitution like that will
overwrite the old value with a value indicating whether or not the
s/// succeeded (the empty string if no match is made, an integer
indicating how many substitutions where made if there was at least
one).
There are other little typos and thinkos in your code, but this is the
only really egregious and subtle one.
When I wrote to Joe about his program I came up with the following
which isn't tested but is the way I would do it without using
Template::Toolkit (which is of course the real solution to this
problem).
#!/usr/bin/perl -w
use strict;
# set up a small table of template tokens mapped to required
# output (note that localtime is called only once).
#
# note that this code fails to compile because of $SCALAR,
# obviously it needs to be initialized by the program.
my %subs = (
'|t|' => scalar localtime,
'|k|' => $SCALAR,
);
# turn the tokens (the stuff on the left-hand-side above) into
# a regular expression which can be matched against, taking
# care to add brackets around it. C<quotemeta> escapes any
# nonalphanumeric characters for you so you don't accidentally
# leave off a "\" escape.
my $regex = join "|", map { quotemeta } keys %subs;
$regex = "($regex)";
# while there's input from DATA (the rest of the program's
# source code), make a substitution if possible, and always
# print the result, even if it did not change.
#
# the original version of this script used the DATA filehandle
# to store the HTML template in the script itself but it is
# omitted here for brevity.
while (<STDIN>) {
s/$regex/$subs{$1}/g;
print;
}
Oh, and Joe, in answer to your query, no, the s/// doesn't need the /e
(eval the right-hand side) modifier anymore because the 'scalar
localtime' is now evaluated once at run-time when building up %subs
(in fact maybe the compiler will even recognize it is a constant and
substitute its value at compile-time).
--
``Oooh! A gingerbread house! Hansel and Gretel are set for life!''
--
* This is list (humbug) general handled by majordomo at lists.humbug.org.au .
* Postings to this list are only accepted from subscribed addresses of
* lists 'general' or 'general-post'. See http://www.humbug.org.au/
More information about the General
mailing list