[31526] in Perl-Users-Digest
Perl-Users Digest, Issue: 2785 Volume: 11
daemon@ATHENA.MIT.EDU (Perl-Users Digest)
Sat Jan 23 11:09:22 2010
Date: Sat, 23 Jan 2010 08:09:06 -0800 (PST)
From: Perl-Users Digest <Perl-Users-Request@ruby.OCE.ORST.EDU>
To: Perl-Users@ruby.OCE.ORST.EDU (Perl-Users Digest)
Perl-Users Digest Sat, 23 Jan 2010 Volume: 11 Number: 2785
Today's topics:
Re: How to dissect a Regexp object? sln@netherlands.com
issue with closedir <globalsec@hotmail.com>
Re: issue with closedir <uri@StemSystems.com>
Re: issue with closedir <globalsec@hotmail.com>
Re: issue with closedir <tadmc@seesig.invalid>
Re: need some help excluding with file::find::rule <globalsec@hotmail.com>
Re: need some help excluding with file::find::rule <someone@example.com>
Re: need some help excluding with file::find::rule <uri@StemSystems.com>
Re: need some help excluding with file::find::rule <tadmc@seesig.invalid>
Re: User-defined substitution <hjp-usenet2@hjp.at>
Re: User-defined substitution <hjp-usenet2@hjp.at>
Re: User-defined substitution <uri@StemSystems.com>
Digest Administrivia (Last modified: 6 Apr 01) (Perl-Users-Digest Admin)
----------------------------------------------------------------------
Date: Fri, 22 Jan 2010 21:29:30 -0800
From: sln@netherlands.com
Subject: Re: How to dissect a Regexp object?
Message-Id: <0t1ll5t3n1aaohh10q3isr9kgglg7ugfn8@4ax.com>
On Fri, 22 Jan 2010 17:54:49 +0000 (UTC), kj <no.email@please.post> wrote:
>Is there a way to tell if a given Regexp object, generated at
>runtime, includes at least one pair of capture parentheses?
>
>More generally, is there any documentation for the Regexp class?
>(I'm referring to the class alluded to by the output of, e.g., ref
>qr//). Running perldoc Regexp fails ("no docs found"), and perldoc
>perlre does not say much at all about this class as such.
>
>TIA!
>
>Kynn
Its not too hard to analyse the string returned by qr//
to get the start (and thereby the count) of capture groups.
To get the actual group text requires some recursion and thought.
use strict;
use warnings;
my $tmp = qr/\(\$th (i(s))(i(s))(i(s))(?:(i\(s)\)(i(s))(i(s))\))/x;
my @capt;
while ($tmp =~ /( (?<!\\)\((?!\?) )/xg ) {
push @capt, pos($tmp);
}
print "$tmp\n";
my ($i,$last) = (1,1);
for my $p (@capt) {
print (' 'x ($p - $last), $i++ % 10);
$last = $p+1;
}
print "\nFound ",scalar @capt, " capture groups\n";
__END__
(?x-ism:\(\$th (i(s))(i(s))(i(s))(?:(i\(s)\)(i(s))(i(s))\)))
1 2 3 4 5 6 7 8 9 0 1
Found 11 capture groups
------------------------------
Date: Sat, 23 Jan 2010 04:17:59 -0800 (PST)
From: solaristar <globalsec@hotmail.com>
Subject: issue with closedir
Message-Id: <7c88a9d4-b4d0-4f1a-8a0f-79d120376924@n7g2000yqb.googlegroups.com>
i had this working with close(DIR); but im trying to do some best
practices code here and apparently closedir is more what i should be
using
here's the relevant code snippet
opendir(my $dh, $basedir) || die "can't open $basedir: $!\n";
my $suff_re = qr/\.[mcu]w\./;
my @servers = grep { !/^\./ && m/$suff_re/ } readdir($dh);
...
...
closedir($dh);
the error
closedir() attempted on invalid dirhandle $dh at ./foo20 line 48.
closedir() attempted on invalid dirhandle $dh at ./foo20 line 48.
line 48 is closedir($dh);
thoughts?
------------------------------
Date: Sat, 23 Jan 2010 07:27:08 -0500
From: "Uri Guttman" <uri@StemSystems.com>
Subject: Re: issue with closedir
Message-Id: <87hbqd80rn.fsf@quad.sysarch.com>
>>>>> "s" == solaristar <globalsec@hotmail.com> writes:
s> i had this working with close(DIR); but im trying to do some best
s> practices code here and apparently closedir is more what i should be
s> using
s> here's the relevant code snippet
s> opendir(my $dh, $basedir) || die "can't open $basedir: $!\n";
s> my $suff_re = qr/\.[mcu]w\./;
s> my @servers = grep { !/^\./ && m/$suff_re/ } readdir($dh);
s> ...
s> ...
s> closedir($dh);
s> the error
s> closedir() attempted on invalid dirhandle $dh at ./foo20 line 48.
s> closedir() attempted on invalid dirhandle $dh at ./foo20 line 48.
s> line 48 is closedir($dh);
without seeing more code, it is hard to tell. the only clue is that you
are getting multiple errors. did $dh get modified somehow before this?
was it closed already before this? perldiag shows this error means you
are closing an already closed dirhandle.
uri
--
Uri Guttman ------ uri@stemsystems.com -------- http://www.sysarch.com --
----- Perl Code Review , Architecture, Development, Training, Support ------
--------- Gourmet Hot Cocoa Mix ---- http://bestfriendscocoa.com ---------
------------------------------
Date: Sat, 23 Jan 2010 04:30:48 -0800 (PST)
From: solaristar <globalsec@hotmail.com>
Subject: Re: issue with closedir
Message-Id: <87851570-7294-4736-b55c-5d8fdc2429bd@m25g2000yqc.googlegroups.com>
On Jan 23, 4:27=A0am, "Uri Guttman" <u...@StemSystems.com> wrote:
> >>>>> "s" =3D=3D solaristar =A0<global...@hotmail.com> writes:
>
> =A0 s> i had this working with close(DIR); but im trying to do some best
> =A0 s> practices code here and apparently closedir is more what i should =
be
> =A0 s> using
>
> =A0 s> here's the relevant code snippet
>
> =A0 s> =A0 =A0 opendir(my $dh, $basedir) || die "can't open $basedir: $!\=
n";
> =A0 s> =A0 =A0 my $suff_re =3D qr/\.[mcu]w\./;
> =A0 s> =A0 =A0 my @servers =3D grep { !/^\./ && m/$suff_re/ } readdir($dh=
);
> =A0 s> =A0 =A0 ...
> =A0 s> =A0 =A0 ...
> =A0 s> =A0 =A0 closedir($dh);
>
> =A0 s> the error
>
> =A0 s> closedir() attempted on invalid dirhandle $dh at ./foo20 line 48.
> =A0 s> closedir() attempted on invalid dirhandle $dh at ./foo20 line 48.
>
> =A0 s> line 48 is closedir($dh);
>
> without seeing more code, it is hard to tell. the only clue is that you
> are getting multiple errors. did $dh get modified somehow before this?
> was it closed already before this? perldiag shows this error means you
> are closing an already closed dirhandle.
>
> uri
>
> --
> Uri Guttman =A0------ =A0u...@stemsystems.com =A0-------- =A0http://www.s=
ysarch.com--
> ----- =A0Perl Code Review , Architecture, Development, Training, Support =
------
> --------- =A0Gourmet Hot Cocoa Mix =A0---- =A0http://bestfriendscocoa.com=
---------
Uri, thanks for the reply, i ended up realizing what i did wrong,
thats what i get for programming at 4:30am (without sleep)
the syntax was right i just had the closedir inside a loop which was
messing things up, i moved it up to be below the line above on my
snippet and works good
:)
------------------------------
Date: Sat, 23 Jan 2010 09:31:59 -0600
From: Tad McClellan <tadmc@seesig.invalid>
Subject: Re: issue with closedir
Message-Id: <slrnhlm5d1.s1m.tadmc@tadbox.sbcglobal.net>
Uri Guttman <uri@StemSystems.com> wrote:
>>>>>> "s" == solaristar <globalsec@hotmail.com> writes:
>
> s> i had this working with close(DIR); but im trying to do some best
> s> practices code here and apparently closedir is more what i should be
> s> using
>
> s> here's the relevant code snippet
If you don't know why it is failing, what makes you think that
you can accurately determine what is relevant?
That is why you should make a short and *complete* program
that illustrates the problem you are having. People should be able
to run your program by copy/pasting the code from your article.
Have you seen the Posting Guidelines that are posted here frequently?
> without seeing more code, it is hard to tell.
Hence the expectation of a short and complete program that
displays the problem being asked about.
--
Tad McClellan
email: perl -le "print scalar reverse qq/moc.liamg\100cm.j.dat/"
------------------------------
Date: Fri, 22 Jan 2010 21:54:47 -0800 (PST)
From: solaristar <globalsec@hotmail.com>
Subject: Re: need some help excluding with file::find::rule
Message-Id: <826bcac4-9130-4c1a-afb6-87c7272b8e29@l19g2000yqb.googlegroups.com>
so i did some more work on my script and i made some headway, wanted
to get another critique, right now its having issues with taking
$server and then getting the $server_w_dir printed properly,
(im not replying to anyone so i removed the previous comments,
hopefully that was the right thing to do :P)
here's the script for critique
#!/usr/bin/perl
use 5.010;
use strict;
use warnings;
use File::Find::Rule;
use File::Basename qw/basename dirname/;
$| = 1;
my @data_dir =
qw { /data/backups };
foreach my $dir (@data_dir) {
print "looking at $dir..\n";
my ( $bkpcount, $dbcount ) = 0;
my %server_w_log;
my %server_w_dir;
opendir( DIR, $dir ) or warn "can't open $dir\n";
my @servers = readdir(DIR);
foreach my $server (@servers) {
my $str = qw#\.(m|c|u)[w]\.#;
chomp $server;
next if $server =~ m/^\./;
next unless $server =~ m/$str/;
print "$server matched\n";
%server_w_log =
map { my $tempfile = basename $_; $tempfile => $_ }
File::Find::Rule->directory->name($server)
->in("$dir/$server/daily.0");
%server_w_dir =
map { my $tempfile = basename $_; $tempfile => $_ }
File::Find::Rule->directory->name(qr/Microsoft\sSQL\sServer/
i)
->in("$dir/$server/daily.0/$server");
}
close(DIR);
# Run this lets find out what it got
foreach my $server ( keys %server_w_log ) {
print "We have this server:\n";
print "$server : \t path is : $server_w_log{$server} \n";
}
# Gather server with sql dirctory
my @backups;
my $total_db_count = 0;
; # this should contain all dbs less than 1 day
# Gather servers with maintenance log
for ( keys %server_w_log ) {
@backups =
File::Find::Rule->file->name(qr/.*\.(bak|BAK)$/)->modified("
=< 1")
->in("$server_w_log{$_}");
my $log = "$server_w_log{$_}/C/maintenanceplan.log";
print "log path is: $log \n";
print "$server_w_log{$_}\n";
# If maintenanceplan.log exist, compare the db backup against it,
output the list on stdout
if ( -f $log ) {
$server_w_log{$_} = $log;
compare_db_w_log( $log, $_, \@backups, \$bkpcount, \
$dbcount );
}
else { print "$log none existing\n"; }
$total_db_count += scalar @backups;
}
------------------------------
Date: Fri, 22 Jan 2010 22:13:54 -0800
From: "John W. Krahn" <someone@example.com>
Subject: Re: need some help excluding with file::find::rule
Message-Id: <Ssw6n.1380$Yt6.940@newsfe23.iad>
solaristar wrote:
>
> My intent is to return any "filename" that contains .[umc]w. within
> the name; for example /data/backups/db01.foobar.mw.blahbalh.com or /
> data3/backups/db02.foobar2.uw.blahblah.com, but NOT
> db01.blahbalah.ml.blahblah.com
In the *code* you posted earlier your path has the string '/daily.0/' in
it but it is not present in your example above so what does the *actual*
path name look like?
John
--
The programmer is fighting against the two most
destructive forces in the universe: entropy and
human stupidity. -- Damian Conway
------------------------------
Date: Sat, 23 Jan 2010 01:26:45 -0500
From: "Uri Guttman" <uri@StemSystems.com>
Subject: Re: need some help excluding with file::find::rule
Message-Id: <87tyud9w0q.fsf@quad.sysarch.com>
>>>>> "s" == solaristar <globalsec@hotmail.com> writes:
s> $| = 1;
again, not needed. it doesn't help with debugging as you think it does.
s> my @data_dir =
s> qw { /data/backups };
s> foreach my $dir (@data_dir) {
s> print "looking at $dir..\n";
s> my ( $bkpcount, $dbcount ) = 0;
s> my %server_w_log;
s> my %server_w_dir;
s> opendir( DIR, $dir ) or warn "can't open $dir\n";
why warn and not die or next? if the dir can't be opened, why continue?
s> my @servers = readdir(DIR);
s> foreach my $server (@servers) {
no need for @servers:
foreach my $server (readdir(DIR)) {
or use File::Slurp which means no need for the opendir and closedir
calls. it also strips . and .. for you.
foreach my $server (read_dir( $dir )) {
s> my $str = qw#\.(m|c|u)[w]\.#;
that is constant and should be factored out of this sub.
the parens are grabbing when a char class is simpler and faster. don't
use alternate delimiters unless / is inside a regex. choose a better
name than $str which conveys no information about this. also why use qw
when you only have one 'word' there. you use this as a regex so it
should be qr.
my $suff_re = qr/\.[mcu]w\./ ;
s> chomp $server;
useless use of chomp. dirs will not have extraneous newlines. if there
is a newline it will be real and in the filename.
s> next if $server =~ m/^\./;
s> next unless $server =~ m/$str/;
s> print "$server matched\n";
s> %server_w_log =
s> map { my $tempfile = basename $_; $tempfile => $_ }
s> File::Find::Rule->directory->name($server)
-> in("$dir/$server/daily.0");
s> %server_w_dir =
s> map { my $tempfile = basename $_; $tempfile => $_ }
s> File::Find::Rule->directory->name(qr/Microsoft\sSQL\sServer/
s> i)
-> in("$dir/$server/daily.0/$server");
s> }
s> close(DIR);
that should be closedir. if you used lexical handles, it would close
upon scope exit and the closedir call wouldn't even be needed. or use
file::slurp as mentioned above
no comments on the guts and logic since i haven't followed your
requirements.
uri
--
Uri Guttman ------ uri@stemsystems.com -------- http://www.sysarch.com --
----- Perl Code Review , Architecture, Development, Training, Support ------
--------- Gourmet Hot Cocoa Mix ---- http://bestfriendscocoa.com ---------
------------------------------
Date: Sat, 23 Jan 2010 09:26:26 -0600
From: Tad McClellan <tadmc@seesig.invalid>
Subject: Re: need some help excluding with file::find::rule
Message-Id: <slrnhlm52k.s1m.tadmc@tadbox.sbcglobal.net>
solaristar <globalsec@hotmail.com> wrote:
> $| = 1;
Why do you think that you need to enable autoflush?
If your answer is still "Trying to debug the program", then:
Why do you think that enabling autoflush helps to debug your program?
I get the feeling that you are doing cargo-cult programming.
You should understand the purpose of ALL of your code.
If you do not understand it then either:
1) do not use it
or
2) ask a question specifically about it
> my $str = qw#\.(m|c|u)[w]\.#;
^ ^
^ ^
How is that different from
my $str = qw#\.(m|c|u)w\.#;
??
Why do you think that the square brackets are needed?
If you don't know what they do then you should either
1) not use it
or
2) ask a question specifically about it
> %server_w_log =
> map { my $tempfile = basename $_; $tempfile => $_ }
> File::Find::Rule->directory->name($server)
> ->in("$dir/$server/daily.0");
Here you STOMP OVER the contents of %server_w_log each time
through the loop, yet you do not use %server_w_log before the
loop finishes.
That is, once you get it "working" you will get output for
only the last directory.
> close(DIR);
You are calling the wrong function here...
> # Run this lets find out what it got
this lets find out what it got on the very last loop iteration, ignoring
all of the work that was done on all of the other loop iterations.
> ; # this should contain all dbs less than 1 day
Why do you think that a semicolon is required there?
If you don't know why, then
1) do not use it
or
2) ask a question specifically about it
> compare_db_w_log( $log, $_, \@backups, \$bkpcount, \
> $dbcount );
Open an editor on your program file.
Find lines that are longer than about 72 characters.
Make them shorter.
compare_db_w_log( $log, $_, \@backups,
\$bkpcount, \$dbcount );
Why do you think that you need to pass a reference to $bkcount
rather than just passing $bkcount?
If you don't know why, then
1) do not use it
or
2) ask a question specifically about it
--
Tad McClellan
email: perl -le "print scalar reverse qq/moc.liamg\100cm.j.dat/"
------------------------------
Date: Sat, 23 Jan 2010 11:27:34 +0100
From: "Peter J. Holzer" <hjp-usenet2@hjp.at>
Subject: Re: User-defined substitution
Message-Id: <slrnhlljon.ms5.hjp-usenet2@hrunkner.hjp.at>
On 2010-01-22 23:17, Ben Morrow <ben@morrow.me.uk> wrote:
> Quoth "Peter J. Holzer" <hjp-usenet2@hjp.at>:
>> I want to provide non-trusted users with a way to make substitutions
>> similar to s///. To my surprise this isn't an FAQ (although there is a
>> similar problem - "How can I expand variables in text strings?"), but
>> maybe I shouldn't be surprised because this is the first time I needed
>> to do that myself ;-).
>>
>> So here is what I came up with - please try to shoot it down:
>>
>>
>> sub replace {
>> my ($string, $pattern, $replacement) = @_;
>>
>> if (my @m = $string =~ m/$pattern/p) {
>> for my $i (1 .. @m) {
>> $replacement =~ s/\$$i(?=\D|)/$m[$i-1]/e;
>> }
>> return ${^PREMATCH} . $replacement . ${^POSTMATCH};
>
> I don't think this behaviour is documented. That is, AIUI
> ${^{PRE,POST}MATCH} should be considered undefined (in the C sense, not
> the Perl sense) after a match which didn't specify /p.
I think you are right. I'm not sure if this is intentional but the
wording in perlvar allows a match to clobber ${^{PRE,POST}MATCH} even if
no /p is present.
That's easily fixed.
>> There is one catch, though: If $pattern doesn't contain any capturing
>> parentheses, @m is set to (1) on a successful match, which isn't
>> distinguishable from a pattern which captures one string "1". I guess I
>> could try to analyze $pattern or just document that at least one set of
>> parentheses must be used.
>
> $#+ gives the number of sets of capturing parens in the last successful
> match.
Hmpf, I should have thought of that. Thanks.
hp
------------------------------
Date: Sat, 23 Jan 2010 13:31:55 +0100
From: "Peter J. Holzer" <hjp-usenet2@hjp.at>
Subject: Re: User-defined substitution
Message-Id: <slrnhllr1u.ms5.hjp-usenet2@hrunkner.hjp.at>
On 2010-01-22 17:54, sln@netherlands.com <sln@netherlands.com> wrote:
> On Fri, 22 Jan 2010 16:01:25 +0100, "Peter J. Holzer" <hjp-usenet2@hjp.at> wrote:
>
>>I want to provide non-trusted users with a way to make substitutions
>>similar to s///. To my surprise this isn't an FAQ (although there is a
>>similar problem - "How can I expand variables in text strings?"), but
>>maybe I shouldn't be surprised because this is the first time I needed
>>to do that myself ;-).
>>
>>
>>So here is what I came up with - please try to shoot it down:
>>
>>
>>sub replace {
>> my ($string, $pattern, $replacement) = @_;
>>
>> if (my @m = $string =~ m/$pattern/p) {
>> for my $i (1 .. @m) {
>> $replacement =~ s/\$$i(?=\D|)/$m[$i-1]/e;
>> }
>> return ${^PREMATCH} . $replacement . ${^POSTMATCH};
>> } else {
>> return $string;
>> }
>>}
>>
>>All three strings are potentially untrusted ($string comes from a
>>database query, $pattern and $replacement are supplied by the user.
>>
>>The function should do the same as
>> $string =~ s/$pattern/$replacement/;
>>except that $<number> references to capture buffers are resolved, too.
>>
>
> I don't know what you are trying to resolve re:
> "except that $<number> references to capture buffers are resolved, too."
Consider:
$string = 'foo';
$pattern = '(f)(o)';
$replacement = '$2$1';
$string =~ s/$pattern/$replacement/;
versus
$string =~ s/$pattern/$2$1/;
In the first case the result is '$2$1o', in the second it is 'ofo'. I
want the second behaviour, i.e., I want to replace $<number> patterns
with the contents of the corresponding capture buffers.
> Can you elaborate?
>
> my ($Str,$Pat,$Rep) = (
> "and \$this end",
> "(\\\$this)",
> "\$1\$1\$1"
> );
> print "\nStr: '$Str'\nPat: '$Pat'\nRepl:'$Rep'\n\n";
> my $res = replace ($Str,$Pat,$Rep);
> print "Str = '$res'\n";
> ---
> Out:
> Str: 'and $this end'
> Pat: '(\$this)'
> Repl:'$1$1$1'
> Str = 'and $this$1$1 end'
> ---
> Which I think is incorrect.
Right. There is a /g modifier missing.
But I noticed a more serious error. Evaluating the $<number> sequences
in numerical order allows double evaluation, e.g.,
replace('aaa$2bbb', '(.*(...))', '$1')
returns 'aaabbbbbb' instead of 'aaa$2bbb'.
The substitutions need to be performed in a strictly left to right
manner. Adding Ben's suggestions and support for \ escapes at the same
time I get:
sub replace2 {
my ($string, $pattern, $replacement) = @_;
if (my @m = $string =~ m/$pattern/p) {
my ($prematch, $postmatch) = (${^PREMATCH}, ${^POSTMATCH});
if ($#+) {
my $new = "";
for (split(/(\$\d+|\\.)/, $replacement)) {
if (/^\$(\d+)/) {
$new .= $m[$1-1];
} elsif (/\\(.)/) {
$new .= $1;
} else {
$new .= $_;
}
}
$replacement = $new;
}
return $prematch . $replacement . $postmatch;
} else {
return $string;
}
}
So it gets more complicated, not simpler as I hoped :-/.
> It remains to be seen wheather the above $Str,$Pat,$Rep can actually
> get in this form via console though.
I see no reason to disallow them.
>>I think this is safe:
>>
>> * The match itself should be safe unless "use re 'eval'" is active
>> (it isn't).
>> * The s///e only evaluates to $m[$i-1], it doesn't evaluate the
>> content, so it cannot be used to inject code.
>>
>>There is one catch, though: If $pattern doesn't contain any capturing
>>parentheses, @m is set to (1) on a successful match, which isn't
>>distinguishable from a pattern which captures one string "1". I guess I
>>could try to analyze $pattern or just document that at least one set of
>>parentheses must be used.
>>
>>Did I miss something? Is there a simpler way?
>
> I don't know about how safe this is. Croaking on code could be as bad as
> injecting code.
It shouldn't croak either.
> Also, only very simple s&r can be done and with no modifiers.
The only modifier I might need is /g - I could add that as an option.
Case conversion might also be useful, so maybe I'll add support for \U,
\L, etc. later. That should fit well into the inner if/elsif cascade.
> Its hard to imagine this could be safely made robust
> for command line usage.
I'm sure it can be made safe and I think it already is.
hp
------------------------------
Date: Sat, 23 Jan 2010 07:42:19 -0500
From: "Uri Guttman" <uri@StemSystems.com>
Subject: Re: User-defined substitution
Message-Id: <87aaw5802c.fsf@quad.sysarch.com>
>>>>> "PJH" == Peter J Holzer <hjp-usenet2@hjp.at> writes:
PJH> Consider:
PJH> $string = 'foo';
PJH> $pattern = '(f)(o)';
PJH> $replacement = '$2$1';
PJH> $string =~ s/$pattern/$replacement/;
PJH> versus
PJH> $string =~ s/$pattern/$2$1/;
PJH> In the first case the result is '$2$1o', in the second it is 'ofo'. I
PJH> want the second behaviour, i.e., I want to replace $<number> patterns
PJH> with the contents of the corresponding capture buffers.
you can't do that directly with $replacement. a /e would probably do
it. why not parse out the $1 yourself and replace it with a substr using
indexes @- and @+? not too hard to do if you don't care about checking
for escaped $'s. even that isn't too much work.
PJH> sub replace2 {
PJH> my ($string, $pattern, $replacement) = @_;
PJH> if (my @m = $string =~ m/$pattern/p) {
PJH> my ($prematch, $postmatch) = (${^PREMATCH}, ${^POSTMATCH});
PJH> if ($#+) {
PJH> my $new = "";
PJH> for (split(/(\$\d+|\\.)/, $replacement)) {
PJH> if (/^\$(\d+)/) {
PJH> $new .= $m[$1-1];
PJH> } elsif (/\\(.)/) {
PJH> $new .= $1;
PJH> } else {
PJH> $new .= $_;
PJH> }
PJH> }
PJH> $replacement = $new;
PJH> }
PJH> return $prematch . $replacement . $postmatch;
PJH> } else {
PJH> return $string;
PJH> }
that all seems way too complicated to me. here is my above idea in VERY
rough logic:
do the match as you do now.
copy @- and @+ so you don't clobber them in the s///
parse the replacement for $1 and do an s/// on that with /e
$replacement =~ s/$(\d+)/substr( $orig_str, $beg[$1], $end[$1] )/eg ;
that's the idea. it needs cleaning up and testing. it really is a simple
templater when you look at it. so this brings up another idea. why not
create your own simpler syntax for the grabs and parse them out yourself
and do something like the above?
>> Its hard to imagine this could be safely made robust
>> for command line usage.
PJH> I'm sure it can be made safe and I think it already is.
my idea is safe as it never executes any user code, just does matching
and replacements later.
uri
--
Uri Guttman ------ uri@stemsystems.com -------- http://www.sysarch.com --
----- Perl Code Review , Architecture, Development, Training, Support ------
--------- Gourmet Hot Cocoa Mix ---- http://bestfriendscocoa.com ---------
------------------------------
Date: 6 Apr 2001 21:33:47 GMT (Last modified)
From: Perl-Users-Request@ruby.oce.orst.edu (Perl-Users-Digest Admin)
Subject: Digest Administrivia (Last modified: 6 Apr 01)
Message-Id: <null>
Administrivia:
To submit articles to comp.lang.perl.announce, send your article to
clpa@perl.com.
Back issues are available via anonymous ftp from
ftp://cil-www.oce.orst.edu/pub/perl/old-digests.
#For other requests pertaining to the digest, send mail to
#perl-users-request@ruby.oce.orst.edu. Do not waste your time or mine
#sending perl questions to the -request address, I don't have time to
#answer them even if I did know the answer.
------------------------------
End of Perl-Users Digest V11 Issue 2785
***************************************