### Reg Ex to find IP address in range

by stew (Scribe)
 on Aug 28, 2003 at 16:20 UTC Need Help??
stew has asked for the wisdom of the Perl Monks concerning the following question:

Hi,

I am trying to determine if a clients IP address is within a certain range. The first two node are fixed so that's not a problem - the last two can be anywhere between 0 and 55 each ie xxx.xxx.0.55 - good xxx.xxx.56.56 - bad

I initially tried
```/^111\.255\.(([0-5])|([0-5]{2}))\.(([0-5])|([0-5]{2}))\$/
but it didn't take me long to figure out that xxx.xxx.48.55 would fail DOH!

It's been a long hard day, if anyone has a quick answer to end my frustration that would be most welcome

Replies are listed 'Best First'.
Re: Reg Ex to find IP address in range
by CombatSquirrel (Hermit) on Aug 28, 2003 at 16:29 UTC
```my @parts = split /\./ \$address;
return (@parts == 4
and \$parts[0] == 111
and \$parts[1] == 255
and ((\$parts[2] > 0 and \$parts[2] < 56
and \$parts[3] >= 0 and \$parts[3] < 56)
or (\$parts[2] == 0 and \$parts[3] == 0)));
Cheers,
CombatSquirrel.
Entropy is the tendency of everything going to hell.
by ybiC (Prior) on Aug 28, 2003 at 17:09 UTC
Re: Reg Ex to find IP address in range
by gjb (Vicar) on Aug 28, 2003 at 16:34 UTC

First of, I assume your IP address is actually valid and in the format you mention in your post.

Now for your problem: why make life hard? The code below is quite simple:

```   my @bytes = split(/\./, \$ip);
if (\$bytes[2] <= 55 && \$bytes[3] <= 55) {
# ok
}

You may -- or even should -- want to look at Net::IP, especially at the bincomp function.

Hope this helps, -gjb-

Re: Reg Ex to find IP address in range
by Kanji (Parson) on Aug 28, 2003 at 16:46 UTC
```/\A   111
[.] 255
[.] ( \d | [1234]\d | 5[012345] )
[.] ( \d | [1234]\d | 5[012345] )
\z/x;

...should work ( with /x modifier used to enhance readability ), but if you're not limited to a regexp, a cleaner ( and more easily reusable!) solution would be something like...

```return 1 if
/\A 111 [.] 255 [.] (\d+) [.] (\d+) \z/x
&& \$1 <= 55
&& \$2 <= 55;

--k.

Update: Fixed typo; thanks CS!

Errrm... Concerning your RegEx: What about '111.255.11.11'? Should be a valid IP, but is not recognized by your pattern. Probably just a typo, change [234] to [1234]. ;-)
Cheers, CombatSquirrel.
Entropy is the tendency of everything going to hell.
Re: Reg Ex to find IP address in range
by NetWallah (Canon) on Aug 28, 2003 at 19:42 UTC

from the docs:

```use NetAddr::IP;
my \$ip = new NetAddr::IP 'loopback';
if (\$ip->within(new     NetAddr::IP "127.0.0.0", "255.0.0.0")) {
}
The module also has many other functions for defining and scanning subnets.
Re: Reg Ex to find IP address in range
by Aristotle (Chancellor) on Aug 28, 2003 at 17:50 UTC
The trick is to think of sequences of digits, not the number they represent. What options exist for the first digit encountered? What conditions have to be met after a certain one of them?
```use strict;
use Test::More 'no_plan';

my \$rx = qr/\A
(?: [0-4]\d? | 5?[0-5] ) \.
(?: [0-4]\d? | 5?[0-5] )
\z/x;

my %test = (
'56.0' => 0,
'0.56' => 0,
'48.56' => 0,
'56.10' => 0,
'55.0' => 1,
'55.55' => 1,
'0.0' => 1,
'10.10' => 1,
);

my \$result;

is(/\$rx/, !!\$result, \$_) while (\$_, \$result) = each %test;

__END__
ok 1 - 0.56
ok 2 - 56.10
ok 3 - 55.0
ok 4 - 55.55
ok 5 - 48.56
ok 6 - 56.0
ok 7 - 10.10
ok 8 - 0.0
1..8

If the first digit seen is any of 0 to 4, then it is legal, and may optionally be followed by any other digit. If it is 5, it is legal, and may optionally be followed by another digit from the 0-5 range. Any other sequence is illegal.

Update: I knew I was missing something when I wrote my test cases.. sigh. And it is so obvious. So there's a third case if the first digit is 6-9: it it is legal if not followed by anything.

```my \$rx = qr/\A
(?: [0-4]\d? | 5?[0-5] | [6-9] ) \.
(?: [0-4]\d? | 5?[0-5] | [6-9]  )
\z/x;
Adding some cases to the test:
```    '62.6' => 0,
'9.97' => 0,
'55.9' => 1,
'1.49' => 1,
'6.7' => 1,
'06.7' => 1,
They all pass. Now let's hope I'm not still a bonehead.

Makeshifts last the longest.

Your regex fails on for instance "7.8".

Abigail

Re: Reg Ex to find IP address in range
by stew (Scribe) on Aug 28, 2003 at 16:32 UTC
Of course.. I'm of to RTFM - Simplicity by Edward DeBono.

Thanks a lot - problem solved
Re: Reg Ex to find IP address in range
by bsb (Priest) on Aug 30, 2003 at 14:27 UTC
I'm right in the middle of Mastering Regular Expressions and he has lots of pretty pictures of how to carve up the lexical domain of strings to permit all and only the right types of numbers. He has IPs, dates and times. Using regexes for these things seems strange and error prone (eg. there was recently a bug in FormBuilder's date regex).

Anyway, here's one the treats the digits as a number. I don't think this is a good solution in this case, but it does escape the lexical prison.

```my \$rx = qr/\A
(\d+) (?(?{ \$1>=0 && \$1<=55 }) | (?!)) \.
(\d+) (?(?{ \$2>=0 && \$2<=55 }) | (?!))
\z/x;

Create A New User
Node Status?
node history
Node Type: perlquestion [id://287429]
Approved by broquaint
help
Chatterbox?
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others wandering the Monastery: (11)
As of 2017-11-22 18:26 GMT
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?
In order to be able to say "I know Perl", you must have:

Results (327 votes). Check out past polls.

Notices?