[24658] in Perl-Users-Digest
Perl-Users Digest, Issue: 6822 Volume: 10
daemon@ATHENA.MIT.EDU (Perl-Users Digest)
Tue Aug 3 14:17:20 2004
Date: Tue, 3 Aug 2004 11:16:24 -0700 (PDT)
From: Perl-Users Digest <Perl-Users-Request@ruby.OCE.ORST.EDU>
To: Perl-Users@ruby.OCE.ORST.EDU (Perl-Users Digest)
Perl-Users Digest Tue, 3 Aug 2004 Volume: 10 Number: 6822
Today's topics:
regex problem with with '|' <mislam@spamless.uiuc.edu>
Re: regex problem with with '|' (Greg Bacon)
Re: regex problem with with '|' <Joe.Smith@inwap.com>
regex search - suggestions? (Sara)
Re: regex search - suggestions? <usenet@vyznev.invalid>
Re: regex search - suggestions? <tadmc@augustmail.com>
Re: regex search - suggestions? (Sara)
regular expression for string substitution (Dave)
Re: regular expression for string substitution <sap6210@rit.edu>
Re: regular expression for string substitution <mritty@gmail.com>
Re: regular expression for string substitution (Dave)
Scanning maillog for IP addresses - Newbie <ggorman@equal-time.com>
search/replace values from an array - Part 2. <mr@sandman.net>
Re: search/replace values from an array - Part 2. (Anno Siegel)
Re: search/replace values from an array - Part 2. <noreply@gunnar.cc>
Re: search/replace values from an array - Part 2. <mr@sandman.net>
Re: search/replace values from an array - Part 2. <mr@sandman.net>
Re: search/replace values from an array - Part 2. (Anno Siegel)
Re: search/replace values from an array - Part 2. <mr@sandman.net>
Digest Administrivia (Last modified: 6 Apr 01) (Perl-Users-Digest Admin)
----------------------------------------------------------------------
Date: Tue, 27 Jul 2004 11:23:42 -0500
From: Sharif Islam <mislam@spamless.uiuc.edu>
Subject: regex problem with with '|'
Message-Id: <ce5via$ju6$1@news.ks.uiuc.edu>
I know this is something very simple, but I can't get the right pattern.
#!/usr/bin/perl -w
use strict;
my @array;
@array=('http://www.url.com?db=hph&db=xyz&jid=ABC%22','http://www.direct.asp?db=npx&db=uib&jn=%22PAW%22',
'http://www.www.com?db=abc&jid=HTY');
print "@array\n";
foreach (@array) {
my @newurl = /db=(.{3})/g ;
my @code1 = /jn|jid=([^%22]{3})/ ;
print @newurl;
print @code1;
print "\n";
}
___OUTPUT___
# perl match.pl
http://www.url?db=hph&db=xyz&jid=ABC%22
http://www.direct.asp?db=npx&db=uib&jn=%22PAW%22
http://www.www.com?db=abc&jid=HTY
hphxyzABC
Use of uninitialized value in print at match.pl line 14.
npxuib
abcHTY
____END OUTPUT___
I want hphxyzABC
npxuibPAW
abcHTY
Why the jn or jid part not working?
Thanks,
--
Sharif
------------------------------
Date: Tue, 27 Jul 2004 16:43:25 -0000
From: gbacon@hiwaay.net (Greg Bacon)
Subject: Re: regex problem with with '|'
Message-Id: <10gd1hdnenfmv2a@corp.supernews.com>
In article <ce5via$ju6$1@news.ks.uiuc.edu>,
Sharif Islam <mislam@uiuc.edu> wrote:
: [...]
: I want hphxyzABC
: npxuibPAW
: abcHTY
Remember that you need to group the alternatives when that's what
you mean:
$ cat try
#! /usr/local/bin/perl
use warnings;
use strict;
my @array = (
'http://www.url.com?db=hph&db=xyz&jid=ABC%22',
'http://www.direct.asp?db=npx&db=uib&jn=%22PAW%22',
'http://www.www.com?db=abc&jid=HTY',
);
$" = "]["; # mjd's array printing trick
for (@array) {
print "$_ matches:\n";
my @newurl = /db=(.{3})/g;
my @code1 = /(?:jn|jid)=(?:%22)?(.{3})/g;
print " \@newurl = [@newurl]\n";
print " \@code1 = [@code1]\n";
}
[gbacon@cslwww gbacon]$ ./try
http://www.url.com?db=hph&db=xyz&jid=ABC%22 matches:
@newurl = [hph][xyz]
@code1 = [ABC]
http://www.direct.asp?db=npx&db=uib&jn=%22PAW%22 matches:
@newurl = [npx][uib]
@code1 = [PAW]
http://www.www.com?db=abc&jid=HTY matches:
@newurl = [abc]
@code1 = [HTY]
Hope this helps,
Greg
--
... history consists of a series of swindles, in which the masses are
first lured into revolt by the promise of Utopia, and then, when they
have done their job, enslaved over again by new masters.
-- George Orwell
------------------------------
Date: Tue, 27 Jul 2004 17:53:35 GMT
From: Joe Smith <Joe.Smith@inwap.com>
Subject: Re: regex problem with with '|'
Message-Id: <zEwNc.169815$%_6.73857@attbi_s01>
Sharif Islam wrote:
> I know this is something very simple, but I can't get the right pattern.
> my @code1 = /jn|jid=([^%22]{3})/ ;
You've got a misunderstanding there. Inside of square brackets, "^" means
a negation of the character class that follows, not beginning of string.
/[^%22]{3}/ is the same as /[^2%]{3}/;
it matches any three characters that are not "%" and not "2".
You'll need to use parens, as Greg Bacon showed.
-Joe
------------------------------
Date: 23 Jul 2004 22:15:08 -0700
From: sa_ravenone@yahoo.com (Sara)
Subject: regex search - suggestions?
Message-Id: <8e3b2dfa.0407232115.7e11c458@posting.google.com>
Hi All,
I have a string (a paragraph) without newlines, with organization
names and their abbreviations in brackets like...
$tmp = "... was proposed by World Health Organisation (WHO) in ...";
I have the following code segment:
$tmp =~ s/\)/\)\n<brk>/g; # because we have . in regex and
# there is no \n in $tmp
my ($abbr,$org) = "";
my (%orgs) = ();
foreach my $line (split (/\n/, $tmp)) {
if ($line =~ /\b([A-Z])(\w+[ forand]*) ([A-Z])(.*?)
\((\1\3[A-Z]*)\)/) {
$abbr = $5; $org = "$1$2 $3$4";
$orgs{$abbr} = $org;
}
}
I added [ forand]* in regex to include 'for', 'of', 'and' that might
appear after the first word.
Can anyone help me to improve the accuracy of this search, especially
the [ forand]* part.
Thanks in advance.
------------------------------
Date: Sat, 24 Jul 2004 10:33:56 +0300
From: Ilmari Karonen <usenet@vyznev.invalid>
Subject: Re: regex search - suggestions?
Message-Id: <slrncg4474.16j.usenet@yhteiskone.vyznev.net>
On 2004-07-24, Sara <sa_ravenone@yahoo.com> wrote:
> Hi All,
> I have a string (a paragraph) without newlines, with organization
> names and their abbreviations in brackets like...
>
> $tmp = "... was proposed by World Health Organisation (WHO) in ...";
...and you want to extract the organization names and abbreviations?
my @tmp = split /\s*\(([A-Z]+)\)/, $tmp;
pop @tmp;
my %orgs;
while (my ($str, $abbr) = splice(@tmp, 0, 2)) {
(my $re = $abbr) =~ s/(.)/$1[a-z\\W]*/g;
$str =~ /.*($re)$/s or warn "Can't expand $abbr!\n" and next;
$orgs{$abbr} = $1;
}
> Can anyone help me to improve the accuracy of this search, especially
If you could provide more sample data, I could do some more thorough
testing. My code works for your example case, and probably quite many
others. Some cases where it fails for various reasons include:
World Wide Web Consortium (W3C)
PlayStation 2 (PS2)
Church of Scientology (CoS)
Skip if Equal (SEQ)
Decrement and Jump if Not Zero (DJN)
Deutscher Jugendbund für Naturbeobachtung (DJN)
GNU's Not Unix (GNU)
Most of those can be fixed, although idiosyncratic abbreviations like
W3C are probably not worth the effort.
--
Ilmari Karonen
If replying by e-mail, please replace ".invalid" with ".net" in address.
------------------------------
Date: Sat, 24 Jul 2004 08:19:00 -0500
From: Tad McClellan <tadmc@augustmail.com>
Subject: Re: regex search - suggestions?
Message-Id: <slrncg4oe4.5u6.tadmc@magna.augustmail.com>
Sara <sa_ravenone@yahoo.com> wrote:
> I added [ forand]* in regex to include 'for', 'of', 'and' that might
> appear after the first word.
That will match exactly the same strings as:
[adfnor ]*
It would match:
aaaaaa
afafafaf
etc.
A character class matches a _character_, not a string.
> Can anyone help me to improve the accuracy of this search, especially
> the [ forand]* part.
(for|of|and)
--
Tad McClellan SGML consulting
tadmc@augustmail.com Perl programming
Fort Worth, Texas
------------------------------
Date: 25 Jul 2004 22:31:20 -0700
From: sa_ravenone@yahoo.com (Sara)
Subject: Re: regex search - suggestions?
Message-Id: <8e3b2dfa.0407252131.4f51179b@posting.google.com>
Ilmari Karonen wrote in message
>...and you want to extract the organization names and abbreviations?
Yes, forgot to mention that :-o
>If you could provide more sample data, I could do some more thorough
>testing. My code works for your example case, and probably quite
many
I have got organization names like ...
European Process Safety Centre (EPSC)
Association of British Chemical Manufacturers (ABCM)
Safety and Reliability Directorate (SRD)
# The next one was not found by your code
Health and Safety at Work etc. Act 1974 (HSWA)
Advisory Committee on Major Hazards (ACMH)
Center for Chemical Process Safety (CCPS)
>Most of those can be fixed, although idiosyncratic abbreviations like
>W3C are probably not worth the effort.
I agree, I don't want to work for it either
Tad McClellan wrote in message
> That will match exactly the same strings as:
> [adfnor ]*
>
> > Can anyone help me to improve the accuracy of this search, especially
> > the [ forand]* part.
>
> (for|of|and)
That was almost exactly what I tried first:
$line =~ /\b([A-Z])(\w+)( for| of| and)? ([A-Z])(.*?)
\((\1\4[A-Z]*)\)/;
$abbr = $6; $org = "$1$2$3 $4$5";
$orgs{$abbr} = $org;
since 'for','of','and' don't get included in abbreviations, but won't
it produce 'Use of uninitialized value in ...' for those which don't
have 'for','of','and'? Is that ignorable?
Thanks,
Sara
------------------------------
Date: 29 Jul 2004 11:36:01 -0700
From: drossign@akamai.com (Dave)
Subject: regular expression for string substitution
Message-Id: <c3a03942.0407291036.53ceb58d@posting.google.com>
I'm trying to use a rename perl script I found in a unix group and I
can't figure out the regular expression I'm supposed to pass it. I
have a file with the name index.cfm?id=6431.html and I want to make
the filename be index_6431.html. So, I thought it would be something
like s/.cfm?id=/_/ but that makes my file name become
_n_ex________6431_html. How can I make it replace the literal string
".cfm?id=" with the literal string "_"?
Thanks,
Dave
------------------------------
Date: 29 Jul 2004 11:57:52 -0700
From: "Steven Pow" <sap6210@rit.edu>
Subject: Re: regular expression for string substitution
Message-Id: <cebhbg$h9c@odah37.prod.google.com>
I feel so smart:-P
$test = 'index.cfm?id=6431.html';
$test =~ s/\.cfm\?id=/_/;
print $test;
That works for me:)
------------------------------
Date: Thu, 29 Jul 2004 15:00:36 -0400
From: Paul Lalli <mritty@gmail.com>
Subject: Re: regular expression for string substitution
Message-Id: <20040729145752.K3404@barbara.cs.rpi.edu>
On Thu, 29 Jul 2004, Dave wrote:
> I'm trying to use a rename perl script I found in a unix group and I
> can't figure out the regular expression I'm supposed to pass it. I
> have a file with the name index.cfm?id=6431.html and I want to make
> the filename be index_6431.html. So, I thought it would be something
> like s/.cfm?id=/_/ but that makes my file name become
> _n_ex________6431_html. How can I make it replace the literal string
> ".cfm?id=" with the literal string "_"?
Looking at your output, I'd have to guess you used the transliteration
operator tr/// or y/// rather than the substitute operator s///. Your
pattern is almost correct, but you need to escape the . and the ?.
$filename =~ s/\.cfm\?id=/_/;
If you're just passing the pattern to some other script, I'd suggest you
take a look at that script to see what it's doing. Again, it should be
using s///, not tr/// or y///
Paul Lalli
------------------------------
Date: 30 Jul 2004 05:29:39 -0700
From: drossign@akamai.com (Dave)
Subject: Re: regular expression for string substitution
Message-Id: <c3a03942.0407300429.24a77cc0@posting.google.com>
Paul,
Thanks for the input. I couldn't quite figure out what the script was
doing. It was a modified version of a script originally written by
Larry Wall so I just took Larry's original script and used that
instead. Escaping the . and ? worked great so now I am in business.
Dave
Paul Lalli <mritty@gmail.com> wrote in message news:<20040729145752.K3404@barbara.cs.rpi.edu>...
> On Thu, 29 Jul 2004, Dave wrote:
> >...snip...
>
> Looking at your output, I'd have to guess you used the transliteration
> operator tr/// or y/// rather than the substitute operator s///. Your
> pattern is almost correct, but you need to escape the . and the ?.
>
> $filename =~ s/\.cfm\?id=/_/;
>
> If you're just passing the pattern to some other script, I'd suggest you
> take a look at that script to see what it's doing. Again, it should be
> using s///, not tr/// or y///
>
> Paul Lalli
------------------------------
Date: Mon, 26 Jul 2004 17:36:05 GMT
From: "Gary Gorman" <ggorman@equal-time.com>
Subject: Scanning maillog for IP addresses - Newbie
Message-Id: <9ibNc.1578$ju6.1191@twister.rdc-kc.rr.com>
Hi All,
I'm looking for help with scanning my maillog file(s) (Sendmail) for IP
addresses to add to the access.db file, so I can block spam. Is there a
script that has already been written that will generate this list for me
where I can just append the addresses to the end of my access file?
------------------------------
Date: Mon, 02 Aug 2004 11:33:38 +0200
From: Sandman <mr@sandman.net>
Subject: search/replace values from an array - Part 2.
Message-Id: <mr-9AB1A1.11333802082004@individual.net>
Hello again, and thanks to Anno Siegel for your answer to my earlier thread
(news:mr-3CA454.18291501082004@individual.net) on the subject, but
unfortunately, the conditions for my need has slightly altered, and I want some
further help (from anyone, not just Anno).
Here is a code snippet that probably illustrates what I want to do:
-------------
#!/usr/bin/perl
use strict;
use warnings;
my $string = "Hello World!";
my %array = (
"Hello (.*?)!", "Goodbye, little #1#!"
# search reply
);
foreach (keys %array){
if ($string=~m/$_/i){
# It matched!
$array{$_}=~s/#(\d+)#/$$1/;
# replace #1# with $1, #2# with $2
# from the match above
print "$string\n\n";
print "$array{$_}\n\n";
# Add the reply to the string
}
}
-------------
Wanted output:
Hello World!
Goodbye, little World!
So, as opposed to my earlier thread, I no longer seek to replace the original
string, but rather add a "reply" to it, if it matches. Basically, what I want
to do is replace the string #1#, #2#, #3#... with the values in $1, $2, $3...
but when trying to do that, perl complains about:
File "test.pl"; Line 15: Can't use string ("1") as a SCALAR ref while
"strict refs" in use
Line 15 being:
$array{$_}=~s/#(\d+)#/$$1/;
Thanks for any help.
--
Sandman[.net]
------------------------------
Date: 2 Aug 2004 10:34:15 GMT
From: anno4000@lublin.zrz.tu-berlin.de (Anno Siegel)
Subject: Re: search/replace values from an array - Part 2.
Message-Id: <cel5b7$66f$1@mamenchi.zrz.TU-Berlin.DE>
Sandman <mr@sandman.net> wrote in comp.lang.perl.misc:
> Hello again, and thanks to Anno Siegel for your answer to my earlier thread
> (news:mr-3CA454.18291501082004@individual.net) on the subject, but
> unfortunately, the conditions for my need has slightly altered, and I want some
> further help (from anyone, not just Anno).
>
>
> Here is a code snippet that probably illustrates what I want to do:
>
> -------------
> #!/usr/bin/perl
> use strict;
> use warnings;
>
> my $string = "Hello World!";
>
> my %array = (
> "Hello (.*?)!", "Goodbye, little #1#!"
> # search reply
> );
> foreach (keys %array){
> if ($string=~m/$_/i){
> # It matched!
>
> $array{$_}=~s/#(\d+)#/$$1/;
Well, this doesn't do what you hope it does. You knew that, and I
showed you a way to do the replacements. Why are you trying it again?
> # replace #1# with $1, #2# with $2
> # from the match above
>
> print "$string\n\n";
> print "$array{$_}\n\n";
> # Add the reply to the string
What does that mean? Append it?
> }
> }
> -------------
>
> Wanted output:
>
> Hello World!
>
> Goodbye, little World!
>
> So, as opposed to my earlier thread, I no longer seek to replace the original
> string, but rather add a "reply" to it, if it matches.
Trivial. Copy the original, modify the copy, concatenate both.
> Basically, what I want
> to do is replace the string #1#, #2#, #3#... with the values in $1, $2, $3...
> but when trying to do that, perl complains about:
>
> File "test.pl"; Line 15: Can't use string ("1") as a SCALAR ref while
> "strict refs" in use
>
> Line 15 being:
>
> $array{$_}=~s/#(\d+)#/$$1/;
I've shown a way to do that in my earlier reply. Your changed
requirements have nothing to do with how to achieve this, you'd have
to do it in any case. So, apply my solution (or another one) to the
new situation. Don't go back to square one, just because an irrelevant
detail has changed.
Anno
------------------------------
Date: Mon, 02 Aug 2004 13:01:01 +0200
From: Gunnar Hjalmarsson <noreply@gunnar.cc>
Subject: Re: search/replace values from an array - Part 2.
Message-Id: <2n6l7qFt2pvlU1@uni-berlin.de>
Sandman wrote:
>
> #!/usr/bin/perl
> use strict;
> use warnings;
>
> my $string = "Hello World!";
>
> my %array = (
Funny name of a hash. ;-)
> "Hello (.*?)!", "Goodbye, little #1#!"
> # search reply
> );
> foreach (keys %array){
> if ($string=~m/$_/i){
> # It matched!
>
> $array{$_}=~s/#(\d+)#/$$1/;
> # replace #1# with $1, #2# with $2
> # from the match above
Besides that you are trying to use a symbolic (or soft) reference,
which is normally not advisable, you are assuming that the $1 variable
contains what was captured from both the last and the previous
matches, and that appears to be somewhat optimistic...
You need to store what was captured from the first match somewhere,
i.e. in a hash:
my %captures = (
1 => $1,
);
$array{$_} =~ s/#(\d+)#/$captures{$1}/;
> print "$string\n\n";
> print "$array{$_}\n\n";
> # Add the reply to the string
> }
> }
> -------------
>
> Wanted output:
>
> Hello World!
>
> Goodbye, little World!
--
Gunnar Hjalmarsson
Email: http://www.gunnar.cc/cgi-bin/contact.pl
------------------------------
Date: Mon, 02 Aug 2004 13:06:55 +0200
From: Sandman <mr@sandman.net>
Subject: Re: search/replace values from an array - Part 2.
Message-Id: <mr-2BE2F0.13065502082004@individual.net>
In article <cel5b7$66f$1@mamenchi.zrz.TU-Berlin.DE>,
anno4000@lublin.zrz.tu-berlin.de (Anno Siegel) wrote:
> > Hello again, and thanks to Anno Siegel for your answer to my earlier thread
> > (news:mr-3CA454.18291501082004@individual.net) on the subject, but
> > unfortunately, the conditions for my need has slightly altered, and I want
> > some
> > further help (from anyone, not just Anno).
> >
> >
> > Here is a code snippet that probably illustrates what I want to do:
> >
> > -------------
> > #!/usr/bin/perl
> > use strict;
> > use warnings;
> >
> > my $string = "Hello World!";
> >
> > my %array = (
> > "Hello (.*?)!", "Goodbye, little #1#!"
> > # search reply
> > );
> > foreach (keys %array){
> > if ($string=~m/$_/i){
> > # It matched!
> >
> > $array{$_}=~s/#(\d+)#/$$1/;
>
> Well, this doesn't do what you hope it does. You knew that, and I
> showed you a way to do the replacements. Why are you trying it again?
I'm not, this is just an illustrative script to givbe the gist of what I want
to do, and while your script worked for the purpose of my earlier needs, it
doesn't for these altered needs, so I went back to this script which doesn't
work, but should give the reader an idea of what I want to achieve.
Plus, your script replaced strings, which I no longer wish to do.
> > # replace #1# with $1, #2# with $2
> > # from the match above
> >
> > print "$string\n\n";
> > print "$array{$_}\n\n";
> > # Add the reply to the string
>
> What does that mean? Append it?
Bad wording. The script should output the original string, with the "reply"
printed after it, with #1#, #2#... expanded into the matched values from the
search string.
> > }
> > }
> > -------------
> >
> > Wanted output:
> >
> > Hello World!
> >
> > Goodbye, little World!
> >
> > So, as opposed to my earlier thread, I no longer seek to replace the
> > original string, but rather add a "reply" to it, if it matches.
>
> Trivial. Copy the original, modify the copy, concatenate both.
>
> > Basically, what I
> > want
> > to do is replace the string #1#, #2#, #3#... with the values in $1, $2,
> > $3...
> > but when trying to do that, perl complains about:
> >
> > File "test.pl"; Line 15: Can't use string ("1") as a SCALAR ref while
> > "strict refs" in use
> >
> > Line 15 being:
> >
> > $array{$_}=~s/#(\d+)#/$$1/;
>
> I've shown a way to do that in my earlier reply. Your changed
> requirements have nothing to do with how to achieve this, you'd have
> to do it in any case. So, apply my solution (or another one) to the
> new situation. Don't go back to square one, just because an irrelevant
> detail has changed.
Well, my problem with your earlier script was this (note the altered string):
#!/usr/bin/perl
use strict;
use warnings;
my %tab = (
'Hello (.*?)!' => 'Goodbye, little #1#...',
'Welcome (.*?) and (.*?)!' => 'Farewell, honorable #2# and fair #1#!',
);
for ( "Welcome ladies and gentlemen! Please step inside", "Hello World!" ) {
my $string = $_; # make a copy we can change
while ( my ( $search, $replace) = each %tab ) {
# build ready-to-use replacement string from template
my $n = 1; # submatch number
for ( $string =~ /$search/ ) { # loop over submatches
$replace =~ s/#$n#/$_/g, # substitute one submatch everywhere
$n ++; # next submatch
}
last if $string =~ s/$search/$replace/;
}
print "$string\n";
}
This outputs
Farewell, honorable gentlemen and fair ladies! Please step inside
Goodbye, little World...
Which is undesirable. And, oddly enough, it only worked occasionally with one
specific string (i.e. running the script five times in a row made it match it
two times, highly bizarre).
So, despite your efforts, I felt I wanted to go back to square one and attack
the faulty line in my little script.
Isn't there a way, while using strict refs, to replace #1#, #2#, #3#... with
the values of $1, $2, $3, which are created by a match operation?
--
Sandman[.net]
------------------------------
Date: Mon, 02 Aug 2004 13:32:24 +0200
From: Sandman <mr@sandman.net>
Subject: Re: search/replace values from an array - Part 2.
Message-Id: <mr-540942.13322402082004@individual.net>
In article <2n6l7qFt2pvlU1@uni-berlin.de>,
Gunnar Hjalmarsson <noreply@gunnar.cc> wrote:
> > foreach (keys %array){
> > if ($string=~m/$_/i){
> > # It matched!
> >
> > $array{$_}=~s/#(\d+)#/$$1/;
> > # replace #1# with $1, #2# with $2
> > # from the match above
>
> Besides that you are trying to use a symbolic (or soft) reference,
> which is normally not advisable, you are assuming that the $1 variable
> contains what was captured from both the last and the previous
> matches, and that appears to be somewhat optimistic...
>
> You need to store what was captured from the first match somewhere,
> i.e. in a hash:
>
> my %captures = (
> 1 => $1,
> );
> $array{$_} =~ s/#(\d+)#/$captures{$1}/;
Aaah, this did the trick. Thanks!
--
Sandman[.net]
------------------------------
Date: 2 Aug 2004 13:05:36 GMT
From: anno4000@lublin.zrz.tu-berlin.de (Anno Siegel)
Subject: Re: search/replace values from an array - Part 2.
Message-Id: <cele70$cjh$1@mamenchi.zrz.TU-Berlin.DE>
Sandman <mr@sandman.net> wrote in comp.lang.perl.misc:
[big snip]
> Isn't there a way, while using strict refs, to replace #1#, #2#, #3#... with
> the values of $1, $2, $3, which are created by a match operation?
Okay, let's treat this in isolation. Suppose you have:
my $string = 'Hello ladies and gentlemen, please step inside';
my $pattern = 'Hello (.*?) and (.*?),';
my $template = 'Farewell honorable #2# and fair #1#';
To do the replacements in the most straightforward way, you could
try this (broken code ahead):
if ( $string =~ /$pattern/ ) {
$template =~ s/#1#/$1/g;
$template =~ s/#2#/$2/g;
}
This doesn't work because we are trying to use $1 and $2 in a
replacement operation. The pattern match that is the first part of
the replacement will destroy the contents of $1 and $2, so we can't
use them that way.
Another problem is that we don't know, in general, how many of $1, $2,...
will be set by $pattern, so we don't know how many replacement lines to
write.
To get around both problems, we can use the fact that a match in list
context returns the captured submatches. So we can loop over them
without knowing how many there are. This action also de-couples the
list elements from the actual variables $1, $2, ..., which is slightly
magical.
We must now generate the marker strings "#1#", "#2#" dynamically.
So:
my $n = 1;
for ( $string =~ /$pattern/ ) {
$template =~ s/#$n#/$_/g;
$n ++;
}
Now $template has been transformed into the reply. $string is
unchanged. This is (in isolation) the same solution I offered before.
Fit it into your scheme of things.
Anno
------------------------------
Date: Mon, 02 Aug 2004 16:14:24 +0200
From: Sandman <mr@sandman.net>
Subject: Re: search/replace values from an array - Part 2.
Message-Id: <mr-B8AD69.16142402082004@individual.net>
In article <cele70$cjh$1@mamenchi.zrz.TU-Berlin.DE>,
anno4000@lublin.zrz.tu-berlin.de (Anno Siegel) wrote:
> Sandman <mr@sandman.net> wrote in comp.lang.perl.misc:
>
> [big snip]
>
> > Isn't there a way, while using strict refs, to replace #1#, #2#, #3#...
> > with
> > the values of $1, $2, $3, which are created by a match operation?
>
> Okay, let's treat this in isolation. Suppose you have:
>
> my $string = 'Hello ladies and gentlemen, please step inside';
> my $pattern = 'Hello (.*?) and (.*?),';
> my $template = 'Farewell honorable #2# and fair #1#';
>
> To do the replacements in the most straightforward way, you could
> try this (broken code ahead):
>
> if ( $string =~ /$pattern/ ) {
> $template =~ s/#1#/$1/g;
> $template =~ s/#2#/$2/g;
> }
>
> This doesn't work because we are trying to use $1 and $2 in a
> replacement operation. The pattern match that is the first part of
> the replacement will destroy the contents of $1 and $2, so we can't
> use them that way.
>
> Another problem is that we don't know, in general, how many of $1, $2,...
> will be set by $pattern, so we don't know how many replacement lines to
> write.
>
> To get around both problems, we can use the fact that a match in list
> context returns the captured submatches. So we can loop over them
> without knowing how many there are. This action also de-couples the
> list elements from the actual variables $1, $2, ..., which is slightly
> magical.
>
> We must now generate the marker strings "#1#", "#2#" dynamically.
> So:
>
> my $n = 1;
> for ( $string =~ /$pattern/ ) {
> $template =~ s/#$n#/$_/g;
> $n ++;
> }
>
> Now $template has been transformed into the reply. $string is
> unchanged. This is (in isolation) the same solution I offered before.
> Fit it into your scheme of things.
Thanks - I think I now understand what you are doing there in greater detail,
which I didn't before.
--
Sandman[.net]
------------------------------
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:
#The Perl-Users Digest is a retransmission of the USENET newsgroup
#comp.lang.perl.misc. For subscription or unsubscription requests, send
#the single line:
#
# subscribe perl-users
#or:
# unsubscribe perl-users
#
#to almanac@ruby.oce.orst.edu.
NOTE: due to the current flood of worm email banging on ruby, the smtp
server on ruby has been shut off until further notice.
To submit articles to comp.lang.perl.announce, send your article to
clpa@perl.com.
#To request back copies (available for a week or so), send your request
#to almanac@ruby.oce.orst.edu with the command "send perl-users x.y",
#where x is the volume number and y is the issue number.
#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 V10 Issue 6822
***************************************