CGI/Perl Guide | Learning Center | Forums | Advertise | Login
Site Search: in

  Main Index MAIN
INDEX
Search Posts SEARCH
POSTS
Who's Online WHO'S
ONLINE
Log in LOG
IN

Home: Perl Programming Help: Beginner:
Extracting last octet from regex capture group possible?

 



asandybox
Novice

Dec 2, 2013, 2:13 PM

Post #1 of 12 (2114 views)
Extracting last octet from regex capture group possible? Can't Post

All,

I'm almost done with my script thanks to help from members on this board.

Stuck on one last problem. Dreaded octet extraction... I need to make a decision based on the last octet in my regex capture, Ex: If 192.168.2.0 = network next;

My regex is working and I have my capture groups just not sure how to get the last octet without killing myself. Here's what I got so far:


Code
#!/usr/bin/perl 

use strict;
use warnings;
use Socket;
use Getopt::Long;
use Time::HiRes qw(gettimeofday tv_interval);
use Net::Ping;

while(<>) {
my $line = $_;
chomp $line;
if ($line =~ m/permit\s(tcp|ip|udp)\s(?:host\s)?(any|\d+\.\d+\.\d+\.\d+)(?:\s255.*)?(?:\s)?(?:host)?\s(any|\d+\.\d+\.\d+\.\d+)\s(?:eq|255.*)\s(.*)/) {
my $proto = $1;
my $src = $2;
my $dst = $3;
my $dst_port = $4;

if ($dst =~ /any/) {
print "dst\=$dst, next\n";
next;
}
elsif ($dst =~ /255.*/) {
print "dst=$dst, next\n";
next;
}
#check if dst_port is a number or not.
if ($dst_port =~ /(^\d+)/) {
#&ping_host($dst);
print "protocol=$proto src=$src dst=$dst dst_port=$dst_port\n";
#system("./check_port.pl -h $dst -p $dst_port");
}
else {
print "dst_port\=null skip\n";
}
}
}

sub ping_host () {
my ($ip_address) = @_;
my $timeout = 1;
my $pinger = Net::Ping->new('icmp', $timeout);

if ($pinger->ping($ip_address)) {
print "pinging $ip_address ping=ok\n";
}
else {
print "ping to $ip_address ping=fail\n";
}
}


The issue is within the $dst capture variable.

I've tried the following with no success whatsoever:


Code
#!/usr/bin/perl 

use strict;
use warnings;
use Socket;
use Getopt::Long;
use Time::HiRes qw(gettimeofday tv_interval);
use Net::Ping;

while(<>) {
my $line = $_;
chomp $line;
if ($line =~ m/permit\s(tcp|ip|udp)\s(?:host\s)?(any|\d+\.\d+\.\d+\.\d+)(?:\s255.*)?(?:\s)?(?:host)?\s(any|\d+\.\d+\.\d+\.\d+)\s(?:eq|255.*)\s(.*)/) {
my $proto = $1;
my $src = $2;
my $dst = $3;
my $dst_port = $4;
my @array = split('.', $dst);
last_octet = @array[0, -1]
#I was hoping at this point I would have the last octet value here so I could make a if decision.

if ($dst =~ /any/) {
print "dst\=$dst, next\n";
next;
}
elsif ($dst =~ /255.*/) {
print "dst=$dst, next\n";
next;
}
#check if dst_port is a number or not.
if ($dst_port =~ /(^\d+)/) {
#&ping_host($dst);
print "protocol=$proto src=$src dst=$dst dst_port=$dst_port\n";
#system("./check_port.pl -h $dst -p $dst_port");
}
else {
print "dst_port\=null skip\n";
}
}
}

sub ping_host () {
my ($ip_address) = @_;
my $timeout = 1;
my $pinger = Net::Ping->new('icmp', $timeout);

if ($pinger->ping($ip_address)) {
print "pinging $ip_address ping=ok\n";
}
else {
print "ping to $ip_address ping=fail\n";
}
}


Any ideas on how to do this elegantly. I was thinking a nested capture group so I also tried the following:


Code
  if ($line =~ m/permit\s(tcp|ip|udp)\s(?:host\s)?(any|\d+\.\d+\.\d+\.\d+)(?:\s255.*)?(?:\s)?(?:host)?\s(any|\d+\.\d+\.\d+\.(\d+))\s(?:eq|255.*)\s(.*)/)


But then I got stumped on how to get the nested match out...


Kenosis
User

Dec 2, 2013, 6:04 PM

Post #2 of 12 (2101 views)
Re: [asandybox] Extracting last octet from regex capture group possible? [In reply to] Can't Post

If you have an IP address in $dst, then why not split it to get the octet you want?

Code
if ( ( split /\./, $dst )[3] == 255 ) { 
...;
}



Laurent_R
Veteran / Moderator

Dec 2, 2013, 11:56 PM

Post #3 of 12 (2092 views)
Re: [asandybox] Extracting last octet from regex capture group possible? [In reply to] Can't Post


Quote

Code
last_octet = @array[0, -1]



Is this supposed to be Perl code? If so, I can see at least 3 major errors and also don't understand the intent.


asandybox
Novice

Dec 3, 2013, 6:11 AM

Post #4 of 12 (2078 views)
Re: [Kenosis] Extracting last octet from regex capture group possible? [In reply to] Can't Post

Thanks Kenosis, again you have come up with a solution!

The issue is I didn't know you could use split this way. The learning "Camel book" I've been reading doesn't discuss split like this. Might need to level up to the "Alpica book", or maybe just keep asking questions =). But I do understand what you did her by splitting on . and then taking the 4 field. Just always under the mindset that you needed to create arrays and split on them while you just act on the scalar variable itself which is cool!

Thanks again.


asandybox
Novice

Dec 3, 2013, 6:13 AM

Post #5 of 12 (2076 views)
Re: [Laurent_R] Extracting last octet from regex capture group possible? [In reply to] Can't Post

Hey I found that solution here:

http://www.ehow.com/how_8760559_remove-last-octet-perl.html

Which made no sense to me, I tried it in my code but didn't return anything.


Kenosis
User

Dec 3, 2013, 7:51 AM

Post #6 of 12 (2067 views)
Re: [asandybox] Extracting last octet from regex capture group possible? [In reply to] Can't Post


Quote
Just always under the mindset that you needed to create arrays and split on them while you just act on the scalar variable itself which is cool!

The ( split /\./, $dst ) creates a list and

Code
( split /\./, $dst )[3]

selects the third element from the list--as an array slice.


FishMonger
Veteran / Moderator

Dec 3, 2013, 7:54 AM

Post #7 of 12 (2064 views)
Re: [Kenosis] Extracting last octet from regex capture group possible? [In reply to] Can't Post

selects the third element from the list--as an array slice.

selects the fourth element from the list--as an array slice.


(This post was edited by FishMonger on Dec 3, 2013, 7:55 AM)


Kenosis
User

Dec 3, 2013, 7:55 AM

Post #8 of 12 (2062 views)
Re: [asandybox] Extracting last octet from regex capture group possible? [In reply to] Can't Post

That array slice example removes the last octet. Notice the @an_array[0, -1] notation. The -1 accesses the last element in the array. Given this,

Code
( split /\./, $dst )[3]

could have been written as

Code
( split /\./, $dst )[-1]



Kenosis
User

Dec 3, 2013, 7:57 AM

Post #9 of 12 (2059 views)
Re: [FishMonger] Extracting last octet from regex capture group possible? [In reply to] Can't Post


Quote
selects the fourth element from the list--as an array slice.

zeroth, first, second, third...

You mistakenly assumed a one-based indexing.


(This post was edited by Kenosis on Dec 3, 2013, 8:01 AM)


FishMonger
Veteran / Moderator

Dec 3, 2013, 8:02 AM

Post #10 of 12 (2052 views)
Re: [Kenosis] Extracting last octet from regex capture group possible? [In reply to] Can't Post


In Reply To

Quote
selects the fourth element from the list--as an array slice.

zeroth, first, second, third...

Don't so quickly assume a one-based indexing.


There is a difference between referring to the 3rd element vs index 3, which is the 4th element.

That difference is the cause of the common "off by 1" error.


(This post was edited by FishMonger on Dec 3, 2013, 8:08 AM)


FishMonger
Veteran / Moderator

Dec 3, 2013, 8:14 AM

Post #11 of 12 (2045 views)
Re: [Kenosis] Extracting last octet from regex capture group possible? [In reply to] Can't Post

Here's another way of looking at this difference.


Code
my @array = qw(1 2 3 4); 

my $number_of_elements = @array;
my $last_index = $#array;

print "Number of elements in array is $number_of_elements\n";
print "Last index number is $last_index\n";



Kenosis
User

Dec 3, 2013, 8:23 AM

Post #12 of 12 (2043 views)
Re: [FishMonger] Extracting last octet from regex capture group possible? [In reply to] Can't Post


Quote
There is a difference between referring to the 3rd element vs the 3rd index, which is the 4th element.


You're simply not accounting for the contextual system within which the expression "3rd element" is being uttered--as if the term "3rd" is somehow categorical. It's actually worse than this. You're conflating two different n-based systems. Ordinality within English doesn't use "zeroth," but begins with "first." Perl, however, uses "zeroth." Thus, your using both English and Perl ordinality when referring to array elements.

Within a system, viz., Perl, whose ordinality uses "0th, 1st, 2nd, 3rd", $x[3] is the third element of the array @x.

"To access the zeroth element of @friends, we write $friends[0]." Source: On Perl: Perl for Students and Professionals

Give this, the third element would be accessed by $friends[3].


Quote
That difference is the cause of the common "off by 1" error.


Conflating English's and Perl's ordinality is the cause of this type of error.


(This post was edited by Kenosis on Dec 3, 2013, 8:45 AM)

 
 


Search for (options) Powered by Gossamer Forum v.1.2.0

Web Applications & Managed Hosting Powered by Gossamer Threads
Visit our Mailing List Archives