Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?

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:


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"; } } }



Replies are listed 'Best First'.
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,

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 TheHobbit (Pilgrim) on Jun 08, 2002 at 17:28 UTC

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

    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...


    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...


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

Log In?

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

How do I use this? | Other CB clients
Other Users?
Others avoiding work at the Monastery: (7)
As of 2023-06-06 15:48 GMT
Find Nodes?
    Voting Booth?
    How often do you go to conferences?

    Results (29 votes). Check out past polls.