[15691] in Perl-Users-Digest
Perl-Users Digest, Issue: 3104 Volume: 9
daemon@ATHENA.MIT.EDU (Perl-Users Digest)
Fri May 19 21:10:37 2000
Date: Fri, 19 May 2000 18:10:15 -0700 (PDT)
From: Perl-Users Digest <Perl-Users-Request@ruby.OCE.ORST.EDU>
To: Perl-Users@ruby.OCE.ORST.EDU (Perl-Users Digest)
Message-Id: <958785015-v9-i3104@ruby.oce.orst.edu>
Content-Type: text
Perl-Users Digest Fri, 19 May 2000 Volume: 9 Number: 3104
Today's topics:
Novice request for help to simplify matching <ra.jones@NO_UCE*cwcom.net>
Re: Novice request for help to simplify matching <jhelman@wsb.com>
Re: Novice request for help to simplify matching <bmb@dataserv.libs.uga.edu>
Re: Novice request for help to simplify matching <jhelman@wsb.com>
Re: Novice request for help to simplify matching <jhelman@wsb.com>
Re: Novice request for help to simplify matching <ra.jones@NO_UCE*cwcom.net>
Re: Novice request for help to simplify matching <jhelman@wsb.com>
Re: Novice request for help to simplify matching <Jonathan.L.Ericson@jpl.nasa.gov>
Re: perl & apache conf (Martin Atkins)
Re: Regular Expression Matching (Abigail)
Re: Return Codes <jeff@vpservices.com>
Re: SQL Server <jhelman@wsb.com>
Re: SQL Server <jeff@vpservices.com>
Digest Administrivia (Last modified: 16 Sep 99) (Perl-Users-Digest Admin)
----------------------------------------------------------------------
Date: Fri, 19 May 2000 23:18:15 +0100
From: jones <ra.jones@NO_UCE*cwcom.net>
Subject: Novice request for help to simplify matching
Message-Id: <TstFvSBn2bJ5Ewl6@cwc.com>
Following advice from an earlier thread, I consulted the PerlFAQ. It is
a HUGE document, and I don't understand the parts I don't understand so
as to solve this problem (if you follow me).
So I would be grateful if you could examine the following code, dealing
with an array - @listr - consisting of several lines (number = $z) of a
log file containing date, time and IP address, in the format:
05/05/00 12:20:20 196.152.120.35
for ($i = 0; $i < $z; $i++) {
($date,$time,$addr) = split(/ /,$listr[$i]);
($ip1,$ip2,$ip3,$ip4) = split(/\./,$addr);
$ipx[$i] = ($ip1 . "\." . $ip2 . "\." . $ip3);
}
if ($ENV{'REMOTE_ADDR'} =~ /$ipx[0]/) { # if remote address matches
'ipx' from 1st line, $xcount = $count
$xcount = $count;
}
elsif ($ENV{'REMOTE_ADDR'} =~ /$ipx[1]/) { # if remote address matches
'ipx' from 2nd line, $xcount = $count - 1
$xcount = $count - 1;
}
etc,
Each line of @listr is split using a single-space de-limiter into date,
time and IP address. The latter of these is then split into its 4
sub-units, and the first 3 are re-joined into a variable called 'ipx'.
Then the REMOTE_ADDR is compared to each 'ipx' and progressively more
intergers are subtracted from $count the further down the list they
match.
The problem is there could be anything from 1 to a very large number in
the @listr array . I have manually written 'if, elsif' statements for
ipx[0] to ipx[9], but I need many more, which gets tedious and is
probably unnecessary. I thought something like: if ($ENV['REMOTE_ADDR'}
=~ /$ipx[$i]/ { $xcount = $count - [$i] } might work, but the [$i]
variable does not seem to exist outside the 'for' section. Can anyone
suggest a work-around for this to save all the repetition?
Many thanks,
--
Richard Jones, Leeds, UK
rajones (at) mail.com
or remove the NO_UCE* from the 'reply-to' address
------------------------------
Date: Fri, 19 May 2000 22:43:35 GMT
From: Jeff Helman <jhelman@wsb.com>
Subject: Re: Novice request for help to simplify matching
Message-Id: <3925C3BA.876F07F@wsb.com>
Okay. I think I understand what you are doing here. Below is the code
that I came up with (if I understood your example correctly). Might I
suggest some optimizations? I'm in no way criticizing you or trying to
make an example or anything like that, but there were some
inefficiencies in your code that are common among the examples that many
beginners submit to the group. I thought that the comments might help
them as well. Hope this helps.
foreach (@listr) { ## NOTE 1
($date, $time, $addr) = split(/ /, $_);
$addr =~ s/\.\d+$//; ## NOTE 2
unshift (@ipx, $addr); ## NOTE 3
}
for ($i = $#ipx; $i >= 0; $i--) { ## NOTE 4
if ($ENV{'REMOTE_ADDR'} =~ /^$ipx[$i]/) { ## NOTE 5
$xcount = $i;
last; ## NOTE 6
}
}
## COMMENTS
1. Lose the for ($i = 0...) loop. Use foreach instead. It's much more
efficient.
2. Since you seem to be chopping off the fourth octet of the IP address
in the file, do a regex replace rather than a split and join.
3. Use the unshift() to add the IP fragment to @ISA. Since you seem to
want a number which indicates the inverse of the array position (First
gives Array Size, Second gives Array Size - 1, etc.) I suggest using
unshift() to build our array backwards so that the score that an match
receives corresponds directly to its position in the array. You could
achieve the same result by using push() to add each element and then
using reverse() to turn them all around, but again, this is more
efficient.
4. Here I am using the for(;;) construct because I want to step
backwards through the array because I assume that your more common
matches were found at the beginning of your file (guessing on this
one). Since I built the array backwards, then, I need to start at the
back. If you aren't familiar with the $# construction, it gives you the
last defined element in the array. Thus, if your array @ipx has 100
elements (with index values of 0 to 99), calling $#ipx will return 99.
5. I'm guessing here, but I assume that you are trying to match the
value from the file to the start of the CGI user's network address.
This is why I inserted the carat (^) character into the regular
expression. If it wasn't there, an IP from your file of 165.181.212.14
would report a match for a user with an IP of 38.165.181.212, for
example. If I'm wrong in this assumption, lose the carat.
6. By calling last here, I break out of the for() loop when I find my
match. This saves me a bunch of processor cycles if my first try finds
a match.
JH
----------------------------------------------------------------
Jeff Helman Product Manager -- Internet Services
jhelman@wsb.com CCH Washington Service Bureau
----------------------------------------------------------------
jones wrote:
>
> Following advice from an earlier thread, I consulted the PerlFAQ. It is
> a HUGE document, and I don't understand the parts I don't understand so
> as to solve this problem (if you follow me).
>
> So I would be grateful if you could examine the following code, dealing
> with an array - @listr - consisting of several lines (number = $z) of a
> log file containing date, time and IP address, in the format:
>
> 05/05/00 12:20:20 196.152.120.35
>
> for ($i = 0; $i < $z; $i++) {
> ($date,$time,$addr) = split(/ /,$listr[$i]);
> ($ip1,$ip2,$ip3,$ip4) = split(/\./,$addr);
> $ipx[$i] = ($ip1 . "\." . $ip2 . "\." . $ip3);
> }
> if ($ENV{'REMOTE_ADDR'} =~ /$ipx[0]/) { # if remote address matches
> 'ipx' from 1st line, $xcount = $count
> $xcount = $count;
> }
> elsif ($ENV{'REMOTE_ADDR'} =~ /$ipx[1]/) { # if remote address matches
> 'ipx' from 2nd line, $xcount = $count - 1
> $xcount = $count - 1;
> }
> etc,
>
> Each line of @listr is split using a single-space de-limiter into date,
> time and IP address. The latter of these is then split into its 4
> sub-units, and the first 3 are re-joined into a variable called 'ipx'.
> Then the REMOTE_ADDR is compared to each 'ipx' and progressively more
> intergers are subtracted from $count the further down the list they
> match.
>
> The problem is there could be anything from 1 to a very large number in
> the @listr array . I have manually written 'if, elsif' statements for
> ipx[0] to ipx[9], but I need many more, which gets tedious and is
> probably unnecessary. I thought something like: if ($ENV['REMOTE_ADDR'}
> =~ /$ipx[$i]/ { $xcount = $count - [$i] } might work, but the [$i]
> variable does not seem to exist outside the 'for' section. Can anyone
> suggest a work-around for this to save all the repetition?
>
> Many thanks,
> --
> Richard Jones, Leeds, UK
> rajones (at) mail.com
> or remove the NO_UCE* from the 'reply-to' address
------------------------------
Date: Fri, 19 May 2000 18:55:09 -0400
From: Brad Baxter <bmb@dataserv.libs.uga.edu>
Subject: Re: Novice request for help to simplify matching
Message-Id: <Pine.GSO.4.21.0005191851350.18271-100000@dataserv.libs.uga.edu>
On Fri, 19 May 2000, Jeff Helman wrote:
...
> foreach (@listr) { ## NOTE 1
> ($date, $time, $addr) = split(/ /, $_);
> $addr =~ s/\.\d+$//; ## NOTE 2
> unshift (@ipx, $addr); ## NOTE 3
> }
> for ($i = $#ipx; $i >= 0; $i--) { ## NOTE 4
> if ($ENV{'REMOTE_ADDR'} =~ /^$ipx[$i]/) { ## NOTE 5
> $xcount = $i;
> last; ## NOTE 6
> }
> }
...
> 5. I'm guessing here, but I assume that you are trying to match the
> value from the file to the start of the CGI user's network address.
> This is why I inserted the carat (^) character into the regular
> expression. If it wasn't there, an IP from your file of 165.181.212.14
> would report a match for a user with an IP of 38.165.181.212, for
> example. If I'm wrong in this assumption, lose the carat.
...
Hmmm, you're not forgetting that '.' is a metacharacter are you?
--
Brad
------------------------------
Date: Fri, 19 May 2000 22:56:31 GMT
From: Jeff Helman <jhelman@wsb.com>
Subject: Re: Novice request for help to simplify matching
Message-Id: <3925C6C2.D0807287@wsb.com>
Oops. I just realized something. The value that I'm returning is
probably 1 less than the value you want (since I'm using the array
element number, which starts at 0). To get the value you want, change
the "$xCount = $i;" line to "$xCount = $i + 1;".
That being said, there's probably an even more efficient way to do
this. If you are just building the @ipx array for this test and never
plan to use it again, then we probably shouldn't build it at all.
Instead, try this:
## ASSUMING THAT $count IS THE SIZE OF YOUR ARRAY
## (i.e. $count = scalar(@listr);)
foreach ($i = 0; $i < $count; $i++) {
($date, $time, $addr) = split(/ /, $_);
$addr =~ s/\.\d+$//;
if ($ENV{'REMOTE_ADDR'} =~ /^$addr/) {
$countx = $count - $i;
last;
}
}
This not only saves you from consuming the memory needed to hold @ipx
(which, as you said, might be large), but it also ends as soon as a
match is found, which saves you from having to go through the entire
list if the first line matches your user's IP address.
Hope this helps,
JH
----------------------------------------------------------------
Jeff Helman Product Manager -- Internet Services
jhelman@wsb.com CCH Washington Service Bureau
----------------------------------------------------------------
Jeff Helman wrote:
>
> Okay. I think I understand what you are doing here. Below is the code
> that I came up with (if I understood your example correctly). Might I
> suggest some optimizations? I'm in no way criticizing you or trying to
> make an example or anything like that, but there were some
> inefficiencies in your code that are common among the examples that many
> beginners submit to the group. I thought that the comments might help
> them as well. Hope this helps.
>
> foreach (@listr) { ## NOTE 1
> ($date, $time, $addr) = split(/ /, $_);
> $addr =~ s/\.\d+$//; ## NOTE 2
> unshift (@ipx, $addr); ## NOTE 3
> }
> for ($i = $#ipx; $i >= 0; $i--) { ## NOTE 4
> if ($ENV{'REMOTE_ADDR'} =~ /^$ipx[$i]/) { ## NOTE 5
> $xcount = $i;
> last; ## NOTE 6
> }
> }
>
> ## COMMENTS
> 1. Lose the for ($i = 0...) loop. Use foreach instead. It's much more
> efficient.
>
> 2. Since you seem to be chopping off the fourth octet of the IP address
> in the file, do a regex replace rather than a split and join.
>
> 3. Use the unshift() to add the IP fragment to @ISA. Since you seem to
> want a number which indicates the inverse of the array position (First
> gives Array Size, Second gives Array Size - 1, etc.) I suggest using
> unshift() to build our array backwards so that the score that an match
> receives corresponds directly to its position in the array. You could
> achieve the same result by using push() to add each element and then
> using reverse() to turn them all around, but again, this is more
> efficient.
>
> 4. Here I am using the for(;;) construct because I want to step
> backwards through the array because I assume that your more common
> matches were found at the beginning of your file (guessing on this
> one). Since I built the array backwards, then, I need to start at the
> back. If you aren't familiar with the $# construction, it gives you the
> last defined element in the array. Thus, if your array @ipx has 100
> elements (with index values of 0 to 99), calling $#ipx will return 99.
>
> 5. I'm guessing here, but I assume that you are trying to match the
> value from the file to the start of the CGI user's network address.
> This is why I inserted the carat (^) character into the regular
> expression. If it wasn't there, an IP from your file of 165.181.212.14
> would report a match for a user with an IP of 38.165.181.212, for
> example. If I'm wrong in this assumption, lose the carat.
>
> 6. By calling last here, I break out of the for() loop when I find my
> match. This saves me a bunch of processor cycles if my first try finds
> a match.
>
> JH
> ----------------------------------------------------------------
> Jeff Helman Product Manager -- Internet Services
> jhelman@wsb.com CCH Washington Service Bureau
> ----------------------------------------------------------------
>
> jones wrote:
> >
> > Following advice from an earlier thread, I consulted the PerlFAQ. It is
> > a HUGE document, and I don't understand the parts I don't understand so
> > as to solve this problem (if you follow me).
> >
> > So I would be grateful if you could examine the following code, dealing
> > with an array - @listr - consisting of several lines (number = $z) of a
> > log file containing date, time and IP address, in the format:
> >
> > 05/05/00 12:20:20 196.152.120.35
> >
> > for ($i = 0; $i < $z; $i++) {
> > ($date,$time,$addr) = split(/ /,$listr[$i]);
> > ($ip1,$ip2,$ip3,$ip4) = split(/\./,$addr);
> > $ipx[$i] = ($ip1 . "\." . $ip2 . "\." . $ip3);
> > }
> > if ($ENV{'REMOTE_ADDR'} =~ /$ipx[0]/) { # if remote address matches
> > 'ipx' from 1st line, $xcount = $count
> > $xcount = $count;
> > }
> > elsif ($ENV{'REMOTE_ADDR'} =~ /$ipx[1]/) { # if remote address matches
> > 'ipx' from 2nd line, $xcount = $count - 1
> > $xcount = $count - 1;
> > }
> > etc,
> >
> > Each line of @listr is split using a single-space de-limiter into date,
> > time and IP address. The latter of these is then split into its 4
> > sub-units, and the first 3 are re-joined into a variable called 'ipx'.
> > Then the REMOTE_ADDR is compared to each 'ipx' and progressively more
> > intergers are subtracted from $count the further down the list they
> > match.
> >
> > The problem is there could be anything from 1 to a very large number in
> > the @listr array . I have manually written 'if, elsif' statements for
> > ipx[0] to ipx[9], but I need many more, which gets tedious and is
> > probably unnecessary. I thought something like: if ($ENV['REMOTE_ADDR'}
> > =~ /$ipx[$i]/ { $xcount = $count - [$i] } might work, but the [$i]
> > variable does not seem to exist outside the 'for' section. Can anyone
> > suggest a work-around for this to save all the repetition?
> >
> > Many thanks,
> > --
> > Richard Jones, Leeds, UK
> > rajones (at) mail.com
> > or remove the NO_UCE* from the 'reply-to' address
------------------------------
Date: Fri, 19 May 2000 23:02:52 GMT
From: Jeff Helman <jhelman@wsb.com>
Subject: Re: Novice request for help to simplify matching
Message-Id: <3925C83F.3F5E5C55@wsb.com>
Oops. Point taken. Can you tell that my brain has pretty much stopped
functioning for the night. :) To be correct, the "if
($ENV{'REMOTE_ADDR'..." line should read:
if ($ENV{'REMOTE_ADDR'} =~ /^\Q$ipx[$i]\E/) {
or, in the case of my second post:
if ($ENV{'REMOTE_ADDR'} =~ /^\Q$addr\E/) {
Good catch. Thanks.
JH
----------------------------------------------------------------
Jeff Helman Product Manager -- Internet Services
jhelman@wsb.com CCH Washington Service Bureau
----------------------------------------------------------------
99 little bugs in the code, 99 bugs in the code.
Fix one bug, compile again, 100 little bugs in the code.
100 little bugs in the code, 100 bugs in the code.
Fix one bug, compile again, 101 little bugs in the code...
---------------------------------------------------------------
Brad Baxter wrote:
>
> On Fri, 19 May 2000, Jeff Helman wrote:
> ...
> > foreach (@listr) { ## NOTE 1
> > ($date, $time, $addr) = split(/ /, $_);
> > $addr =~ s/\.\d+$//; ## NOTE 2
> > unshift (@ipx, $addr); ## NOTE 3
> > }
> > for ($i = $#ipx; $i >= 0; $i--) { ## NOTE 4
> > if ($ENV{'REMOTE_ADDR'} =~ /^$ipx[$i]/) { ## NOTE 5
> > $xcount = $i;
> > last; ## NOTE 6
> > }
> > }
> ...
> > 5. I'm guessing here, but I assume that you are trying to match the
> > value from the file to the start of the CGI user's network address.
> > This is why I inserted the carat (^) character into the regular
> > expression. If it wasn't there, an IP from your file of 165.181.212.14
> > would report a match for a user with an IP of 38.165.181.212, for
> > example. If I'm wrong in this assumption, lose the carat.
> ...
>
> Hmmm, you're not forgetting that '.' is a metacharacter are you?
>
> --
> Brad
------------------------------
Date: Sat, 20 May 2000 00:04:52 +0100
From: jones <ra.jones@NO_UCE*cwcom.net>
Subject: Re: Novice request for help to simplify matching
Message-Id: <PbhyixBUicJ5EwVW@cwc.com>
Jeff,
Thanks for that. Optimisations (indeed any suggestions) welcome. It is
late here in the UK, so I will try to absorb this and test it tomorrow.
One point perhaps I could clarify though, which wasn't in my original
post. The @listr array is already reversed - @listr = reverse(@list) - ,
so I subtract increasing numbers from $count the further *UP* the list
the IP matches. Is your code still applicable in this situation?
On Fri, 19 May 2000 at 22:43:35, Jeff Helman <jhelman@wsb.com> wrote:
>Okay. I think I understand what you are doing here. Below is the code
>that I came up with (if I understood your example correctly). Might I
>suggest some optimizations? I'm in no way criticizing you or trying to
>make an example or anything like that, but there were some
>inefficiencies in your code that are common among the examples that
>many
>beginners submit to the group. I thought that the comments might help
>them as well. Hope this helps.
>
>foreach (@listr) { ## NOTE 1
> ($date, $time, $addr) = split(/ /, $_);
> $addr =~ s/\.\d+$//; ## NOTE 2
> unshift (@ipx, $addr); ## NOTE 3
>}
>for ($i = $#ipx; $i >= 0; $i--) { ## NOTE 4
> if ($ENV{'REMOTE_ADDR'} =~ /^$ipx[$i]/) { ## NOTE 5
> $xcount = $i;
> last; ## NOTE 6
> }
>}
>
>## COMMENTS
>1. Lose the for ($i = 0...) loop. Use foreach instead. It's much more
>efficient.
>
>2. Since you seem to be chopping off the fourth octet of the IP address
>in the file, do a regex replace rather than a split and join.
>
>3. Use the unshift() to add the IP fragment to @ISA. Since you seem to
>want a number which indicates the inverse of the array position (First
>gives Array Size, Second gives Array Size - 1, etc.) I suggest using
>unshift() to build our array backwards so that the score that an match
>receives corresponds directly to its position in the array. You could
>achieve the same result by using push() to add each element and then
>using reverse() to turn them all around, but again, this is more
>efficient.
>
>4. Here I am using the for(;;) construct because I want to step
>backwards through the array because I assume that your more common
>matches were found at the beginning of your file (guessing on this
>one). Since I built the array backwards, then, I need to start at the
>back. If you aren't familiar with the $# construction, it gives you the
>last defined element in the array. Thus, if your array @ipx has 100
>elements (with index values of 0 to 99), calling $#ipx will return 99.
>
>5. I'm guessing here, but I assume that you are trying to match the
>value from the file to the start of the CGI user's network address.
>This is why I inserted the carat (^) character into the regular
>expression. If it wasn't there, an IP from your file of 165.181.212.14
>would report a match for a user with an IP of 38.165.181.212, for
>example. If I'm wrong in this assumption, lose the carat.
>
>6. By calling last here, I break out of the for() loop when I find my
>match. This saves me a bunch of processor cycles if my first try finds
>a match.
>
>JH
>----------------------------------------------------------------
>Jeff Helman Product Manager -- Internet Services
>jhelman@wsb.com CCH Washington Service Bureau
>----------------------------------------------------------------
--
Richard Jones, Leeds, UK
rajones (at) mail.com
------------------------------
Date: Fri, 19 May 2000 23:11:51 GMT
From: Jeff Helman <jhelman@wsb.com>
Subject: Re: Novice request for help to simplify matching
Message-Id: <3925CA5A.8E4F9634@wsb.com>
Okay. So if I get you correctly, if the first line in the file matches
the user's IP, then $xcount is given a value of 1? If so, do this:
foreach ($i = $count; $i > 0; $i--) {
($date, $time, $addr) = split(/ /, $_);
$addr =~ s/\.\d+$//;
## NOTE THE CHANGE HERE -- THANKS, BRAD
if ($ENV{'REMOTE_ADDR'} =~ /^\Q$addr\E/) {
$countx = $i;
last;
}
}
If the first line in the file should return 0, just subtract 1 from
whatever value of $countx this thing returns.
JH
jones wrote:
>
> Jeff,
>
> Thanks for that. Optimisations (indeed any suggestions) welcome. It is
> late here in the UK, so I will try to absorb this and test it tomorrow.
> One point perhaps I could clarify though, which wasn't in my original
> post. The @listr array is already reversed - @listr = reverse(@list) - ,
> so I subtract increasing numbers from $count the further *UP* the list
> the IP matches. Is your code still applicable in this situation?
>
> On Fri, 19 May 2000 at 22:43:35, Jeff Helman <jhelman@wsb.com> wrote:
> >Okay. I think I understand what you are doing here. Below is the code
> >that I came up with (if I understood your example correctly). Might I
> >suggest some optimizations? I'm in no way criticizing you or trying to
> >make an example or anything like that, but there were some
> >inefficiencies in your code that are common among the examples that
> >many
> >beginners submit to the group. I thought that the comments might help
> >them as well. Hope this helps.
> >
> >foreach (@listr) { ## NOTE 1
> > ($date, $time, $addr) = split(/ /, $_);
> > $addr =~ s/\.\d+$//; ## NOTE 2
> > unshift (@ipx, $addr); ## NOTE 3
> >}
> >for ($i = $#ipx; $i >= 0; $i--) { ## NOTE 4
> > if ($ENV{'REMOTE_ADDR'} =~ /^$ipx[$i]/) { ## NOTE 5
> > $xcount = $i;
> > last; ## NOTE 6
> > }
> >}
> >
> >## COMMENTS
> >1. Lose the for ($i = 0...) loop. Use foreach instead. It's much more
> >efficient.
> >
> >2. Since you seem to be chopping off the fourth octet of the IP address
> >in the file, do a regex replace rather than a split and join.
> >
> >3. Use the unshift() to add the IP fragment to @ISA. Since you seem to
> >want a number which indicates the inverse of the array position (First
> >gives Array Size, Second gives Array Size - 1, etc.) I suggest using
> >unshift() to build our array backwards so that the score that an match
> >receives corresponds directly to its position in the array. You could
> >achieve the same result by using push() to add each element and then
> >using reverse() to turn them all around, but again, this is more
> >efficient.
> >
> >4. Here I am using the for(;;) construct because I want to step
> >backwards through the array because I assume that your more common
> >matches were found at the beginning of your file (guessing on this
> >one). Since I built the array backwards, then, I need to start at the
> >back. If you aren't familiar with the $# construction, it gives you the
> >last defined element in the array. Thus, if your array @ipx has 100
> >elements (with index values of 0 to 99), calling $#ipx will return 99.
> >
> >5. I'm guessing here, but I assume that you are trying to match the
> >value from the file to the start of the CGI user's network address.
> >This is why I inserted the carat (^) character into the regular
> >expression. If it wasn't there, an IP from your file of 165.181.212.14
> >would report a match for a user with an IP of 38.165.181.212, for
> >example. If I'm wrong in this assumption, lose the carat.
> >
> >6. By calling last here, I break out of the for() loop when I find my
> >match. This saves me a bunch of processor cycles if my first try finds
> >a match.
> >
> >JH
> >----------------------------------------------------------------
> >Jeff Helman Product Manager -- Internet Services
> >jhelman@wsb.com CCH Washington Service Bureau
> >----------------------------------------------------------------
> --
> Richard Jones, Leeds, UK
> rajones (at) mail.com
------------------------------
Date: Fri, 19 May 2000 16:24:54 -0700
From: Jon Ericson <Jonathan.L.Ericson@jpl.nasa.gov>
Subject: Re: Novice request for help to simplify matching
Message-Id: <3925CD46.F2E61E6D@jpl.nasa.gov>
jones wrote:
> Following advice from an earlier thread, I consulted the PerlFAQ. It is
> a HUGE document, and I don't understand the parts I don't understand so
> as to solve this problem (if you follow me).
Actually, the FAQ for perl is 10 large documents (perlfaq and
perlfaq[1-9]). Type 'perldoc perlfaq' to get a 'Structural overview of
the FAQ'. perldoc can be a big help when it comes to sorting through
the perl documentation. The command 'perldoc perldoc' will give you
more information. (Notice the helpful -q option.)
Jon
--
Knowledge is that which remains when what is
learned is forgotten. - Mr. King
------------------------------
Date: Fri, 19 May 2000 22:12:57 GMT
From: zneg.ngxvaf@ovtsbbg.pbz (Martin Atkins)
Subject: Re: perl & apache conf
Message-Id: <3922d87e.12162448@news.vossnet.net>
On Tue, 16 May 2000 11:46:51 +0100, "Ian"
<duxbury@kentmere23.freeserve.co.uk> posted:
>I have changed the shebang line as you suggested, I'm using Win98 so I have
>changed it as below. The error log is still reading:-
>
>[Tue May 16 11:42:29 2000] [error] [client 127.0.0.1] (2)No such file or
>directory: couldn't spawn child process: c:/program files/apache
>group/apache/cgi-bin/p20_5.pl
>
>
>#!c:\progra~1\apache~1\apache\cgi-bin\p20_5.pl
>
You need to specify the path to perl.exe, not the path to your script. You
should also specify it using slashes rather than backslashes, eg:
#!c:/perl/bin/perl.exe
Kind Regards,
-Martin
|\/| _..__|_o._ /\_|_| o._ _ mart.atkins@--
| |(_|| |_|| | /--\|_|<|| |_> --bigfoot.com
------------------------------
Date: 19 May 2000 22:25:48 GMT
From: abigail@foad.org (Abigail)
Subject: Re: Regular Expression Matching
Message-Id: <slrn8ibfra.vii.abigail@ucan.foad.org>
On Fri, 19 May 2000 15:08:51 -0400, Mike Masinick <mike@sinfonia.net> wrote:
++ For some reason I can't write a new message to the list, only reply...
++ so I hope somebody reads this :)
Perhaps you shouldn't use Netscape.... ;-)
++ Hey all, please let me know if you can solve this problem for me:
++
++ I have the following text:
++
++ {{558796 {2 OF AMERIKAZ MOST WANTED} {} {2PAC/SNOOP DOGGY DOGG} 246 0}
++ {558982 {NUTHIN' BUT A 'G' THANG} {} {DR. DRE/SNOOP DOGGY DOGG} 238 0}
++ {559243
++ {THE SHIZNIT} {} {SNOOP DOGGY DOGG} 255 0} {558919 {UP JUMP THA BOOGIE}
++ {}
++ {SNOOP DOGGY DOGG/WILSON/MARIE} 283 0} {558967 BLUEBERRY {} {SNOOP DOGGY
++ DOGG} 255 0} {559207 {DOGGY DOGG WORLD} {} {SNOOP DOGGY DOGG/DRAMATICS}
++ 280 0} {559102 {I WISH} {} {DOGG POUND} 296 0} {559024 {WHAT WOULD U
++ DO?} {} {DOGG
++ POUND} 308 0}}
++
++
++ I need to remove all of the first numbers in each of the smaller
++ expressions which all take the
++ form {NUMBER1 {TITLE} {} {ARTIST} NUMBER2 NUMBER3}.
Actually, they don't.
{558967 BLUEBERRY {} {SNOOP DOGGY DOGG} 255 0}
doesn't have braces around the title.
++ I have tried all sorts of expression matching problems, but have not yet
++ been able to
++ successfully retreive those numbers. For the text above, I would like
Perhaps a regex isn't the best solution. Here's one based on
Parse::RecDescent.
#!/opt/perl/bin/perl -w
use strict;
use Parse::RecDescent;
my $grammar = <<'EOG';
number: /\d+/
block: '{' /[^}]*/ '}'
| /\S*/
list: '{' record(s) '}' {$item [2]}
record: '{' number title '{}' artist number number '}' {$item [2]}
title: block
artist: block
EOG
my $parser = Parse::RecDescent -> new ($grammar);
local $/;
my $result = $parser -> list (<DATA>) or die "Bad text!\n";
print "@$result\n";
__DATA__
{{558796 {2 OF AMERIKAZ MOST WANTED} {} {2PAC/SNOOP DOGGY DOGG} 246 0}
{558982 {NUTHIN' BUT A 'G' THANG} {} {DR. DRE/SNOOP DOGGY DOGG} 238 0}
{559243
{THE SHIZNIT} {} {SNOOP DOGGY DOGG} 255 0} {558919 {UP JUMP THA BOOGIE}
{}
{SNOOP DOGGY DOGG/WILSON/MARIE} 283 0} {558967 BLUEBERRY {} {SNOOP DOGGY
DOGG} 255 0} {559207 {DOGGY DOGG WORLD} {} {SNOOP DOGGY DOGG/DRAMATICS}
280 0} {559102 {I WISH} {} {DOGG POUND} 296 0} {559024 {WHAT WOULD U
DO?} {} {DOGG
POUND} 308 0}}
This will print
558796 558982 559243 558919 558967 559207 559102 559024
Abigail
------------------------------
Date: Fri, 19 May 2000 16:11:28 -0700
From: Jeff Zucker <jeff@vpservices.com>
Subject: Re: Return Codes
Message-Id: <3925CA20.9AC672FE@vpservices.com>
Jon Ericson wrote:
>
> Backticks return the 'collected standard output of the command'
> (perlop), _not_ the return code of the command. The exit status is
> stored in $?. Perhaps you meant:
>
> my $return_code = system '/usr/bin/mt -t /dev/rmt/0m rew';
>
> since system _does_ return the return code of the command.
Duh! I was too busy with my puns to pay attention. Thanks for the
correction.
--
Jeff
------------------------------
Date: Fri, 19 May 2000 22:09:10 GMT
From: Jeff Helman <jhelman@wsb.com>
Subject: Re: SQL Server
Message-Id: <3925BBA8.BA9F2B0C@wsb.com>
Amy Brownlee wrote:
>
> Is it possible to use Perl to hit a MS SQL 7.0 Server? Where can I find
> more info about this? Any responses will be appreciated.
>
It can be either very easy or distinctly painful, depending on client
platform you are using. If you are running your client on Win 9x or NT,
download Dave Roth's Win32::ODBC module from CPAN (or, if you are
running ActivePerl from ActiveState, type PPM from the command line and
then type install Win32-ODBC to install the module).
Win32::ODBC isn't perfect, but it get's the job done. I use on a daily
basis and it works for me. The documentation is pretty good.
If you are running linux, some flavor of Unix or something else, well,
all bets are off. You might try one of the DBI family of modules (with
the Sybase DBD, probably), but I have no idea how that works.
Hope this helps,
JH
----------------------------------------------------------------
Jeff Helman Product Manager -- Internet Services
jhelman@wsb.com CCH Washington Service Bureau
----------------------------------------------------------------
99 little bugs in the code, 99 bugs in the code.
Fix one bug, compile again, 100 little bugs in the code.
100 little bugs in the code, 100 bugs in the code.
Fix one bug, compile again, 101 little bugs in the code...
----------------------------------------------------------------
------------------------------
Date: Fri, 19 May 2000 17:59:11 -0700
From: Jeff Zucker <jeff@vpservices.com>
Subject: Re: SQL Server
Message-Id: <3925E35F.39011F1E@vpservices.com>
Amy Brownlee wrote:
>
> Is it possible to use Perl to hit a MS SQL 7.0 Server? Where can I find
> more info about this? Any responses will be appreciated.
The Perl DBI (DataBase Interface) project is a huge ongoing software
project within Perl aimed at making, as much as possible, a single
interface to all relational database management systems. It works with
a series of DataBase Drivers (DBDs) for each kind of database
DBD::Oracle, DBD::mysql, etc. For most purposes, one can mix and match
the drivers, e.g. creating a script to run with one backend and then
using the script with another backend later with only a few minor
changes. There are several drivers that work in one way or another with
MS SQL Server: DBD::ODBC, DBD::Sybase, DBD::Ado, DBD::freeTDS. You can
find out more at http://www.symbolstone.org/technology/perl/DBI/.
Additionally there is a stand-alone module called Win32::ODBC which is
not compatible with the DBI project. It does allow you to do a few more
things with ODBC compliant databases than the DBD::ODBC does and many
people are satisfied with it, but at the cost of portability to other
systems and lacking the multiple books, newsgroups, etc. devoted to
DBI. The DBI FAQ at the URL above goes into a bit more detail on a
comparison of those two.
Good luck!
--
Jeff
------------------------------
Date: 16 Sep 99 21:33:47 GMT (Last modified)
From: Perl-Users-Request@ruby.oce.orst.edu (Perl-Users-Digest Admin)
Subject: Digest Administrivia (Last modified: 16 Sep 99)
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: The mail to news gateway, and thus the ability to submit articles
| through this service to the newsgroup, has been removed. I do not have
| time to individually vet each article to make sure that someone isn't
| abusing the service, and I no longer have any desire to waste my time
| dealing with the campus admins when some fool complains to them about an
| article that has come through the gateway instead of complaining
| to the source.
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 V9 Issue 3104
**************************************