Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

perl regex with '\s+'

by emcb (Beadle)
on Jun 08, 2002 at 09:58 UTC ( #172761=perlquestion: print w/ replies, xml ) Need Help??
emcb has asked for the wisdom of the Perl Monks concerning the following question:

Hi,

I have a problem with this regex. It seems to keep the spaces when i thought the \s+ part would not catch them.

Hers the code:

#! D:\perl\bin\perl # # CGI script to display the status of tcp/udp/raw connections on the s +erver. # Will give you a warning is there are any SYN'ers. BEGIN { use strict; print "Content-Type: text/plain\n\n"; use CGI::Carp 'fatalsToBrowser'; use warnings; } &netstat('-an'); sub netstat { my $args = shift; my $line; my @lines = `netstat $args`; print "$0: running \'netstat $args\'\n\n"; my($prot,$laddr,$lport,$eaddr,$eport,$status,$syn); LOOP: foreach $line (@lines) { $_ = $line; next LOOP if /^Active Connections/; next LOOP if /^$/; next LOOP if /^\s+Proto/; if(/^\s+(.*)\s+(.*):(.*)\s+(.*):(.*)\s+(.*)/) { $prot = $1; $laddr = $2; $lport = $3; $eaddr = $4; $eport = $5; $status = $6; $syn = 0; if($status =~ /syn/i) { $syn = $status; } print "\nwarning: $status! I think we're being SYN'ed\n\n" + if $syn; print "Local: $laddr:$lport - External: $eaddr:$eport - ", +$syn || $status,"\n"; } } }

Cheers,

Elfyn

Comment on perl regex with '\s+'
Download Code
Re: perl regex with '\s+'
by Juerd (Abbot) on Jun 08, 2002 at 10:06 UTC

    .* grabs all remaining. Maybe you meant \S* or .*? there?

    - Yes, I reinvent wheels.
    - Spam: Visit eurotraQ.
    

Re: perl regex with '\s+'
by Zaxo (Archbishop) on Jun 08, 2002 at 11:38 UTC

    Here's another way to parse the socket lines:

    my ($prot,$recv_q,$send_q,$laddr,$lport,$eaddr,$eport,$status,$syn) = map {split ':'} split " ";
    You could also take another approach to forking the netstat process. Use magical open to make netstat's STDOUT pipe to a handle in the parent, and process the lines as you read them:
    open NETSTAT, '-|', '/bin/netstat', '-na' or die $!; while (<NETSTAT>) { next if /^Active/ or /^\s+Proto/ or /^$/; my @sockdata = map {split ':'} split " "; print "$/Warning: SYN! I think we're being SYN'ed$/$/" if $sockdata[7] =~ /syn/i; printf "Local: %s:%s - External: %s:%s - %s$/", @sockdata[3..7]; }
    You could keep the SYN matches, and recheck after a little sleep to verify SYN flood attacks.

    Update: Corrected code to match my netstat output.

    After Compline,
    Zaxo

Re: perl regex with '\s+'
by TheHobbit (Pilgrim) on Jun 08, 2002 at 17:28 UTC

    Hi,
    As is frequently the case, the problem cames from misunderstunding greadines of RE + and * operators. Let us take

    /\s+(.*)\s+(.*)/
    which is a simpler version of your RE, and try and match it against "___abc___def" (the "_" represents spaces). First, perl matches \s+ against the three spaces, and the first (.*) against all the other acaracters (that is "abc___def". But now there is a \s+, which require at least a space, so the first .* grundly gives back one character at time, until it only matches "abc__" (two spaces). Now \s+ matches this space, and the second (.*) is free to match "def". After that, $1 is "abc__", and $2 is "def".

    I hope this explain things...

    Cheers


    Leo TheHobbit

      Thanks fellow monks. I'm still learning re's so that got me. And i think i'll start using the 'magic' open on these ones...

      Elfyn

        \s+ change consecutive spaces to single spaces \s* remove all spaces altogether;

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://172761]
Approved by Zaxo
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others about the Monastery: (6)
As of 2015-07-06 03:14 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (69 votes), past polls