http://qs321.pair.com?node_id=380612

Inspired by Regexp to match IP address, I thought of golfing the smallest Perl expression (not necessarily a regular expression) that, when using strict and warnings, evaluates to true if $_ is a valid numeric IPv4 decimal address.

Those addresses can be:

    A single decimal number between 0 and 256 ** 4 - 1
    Two decimal numbers separated by a dot, the first between 0 and 255 and the second between 0 and 256 ** 3 - 1
    Three decimal numbers separated by a dot, the first two between 0 and 255 and the third between 0 and 65535
    The more usual four decimal numbers between 0 and 255 separated by a dot

Here is the first naive attempt to get the ball rolling. It's 24 + 39 + 54 + 64 = 181 characters, easy to beat!

Update: It looks like I didn't make myself clear, when I said "smallest expression" I meant "smallest valid Perl expression", I didn't mean "regular expression"

# 1 2 3 4 5 6 #234567890123456789012345678901234567890123456789012345678901234 (/^(\d+)$/&&$1<256**4)|| (/^(\d+)\.(\d+)$/&&$1<256&&$2<256**3)|| (/^(\d+)\.(\d+)\.(\d+)$/&&$1<256&&$2<256&&$3<256**2)|| (/^(\d+)\.(\d+)\.(\d+)\.(\d+)$/&&$1<256&&$2<256&&$3<256&&$4<256)

Replies are listed 'Best First'.
Re: (Golf) Expression for matching numeric IP addresses
by BrowserUk (Patriarch) on Aug 06, 2004 at 18:12 UTC

    Not a regex, but it works fine for decimal encoded IPs.

    sub validIP{ use List::Util qw[ reduce ]; $a = $b; $_[0] =~ m[^[\d\.]+$] and 2**32 > reduce{ $a * 256 + ($b < 256 ? $b : 1e99) } reverse split '\.', $_[0] }


    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "Think for yourself!" - Abigail
    "Memory, processor, disk in that order on the hardware side. Algorithm, algorithm, algorithm on the code side." - tachyon
Re: (Golf) Expression for matching numeric IP addresses
by hv (Prior) on Aug 10, 2004 at 13:32 UTC

    Here's a different approach specifically for the 4-element dotted form:

    (eval$_)=~/^[\0-\xff]{4}\z/

    This requires perl-5.6.0 or later; extending it for the other forms becomes rather uglier:

    (eval"0.0.$_")=~/^\0\0(.|[\0-\xff]([\0-\x{ffffff}]|[\0-\xff]([\0-\x{ +ffff}]|[\0-\xff]{2})))\z/s

    Of course the usual caveats about eval apply, but this is golf ...

    Hugo

Re: (Golf) Expression for matching numeric IP addresses
by Aristotle (Chancellor) on Aug 06, 2004 at 21:47 UTC

    To be honest, I don't have the patience to do this manually, right now. A much more interesting problem would be writing a somewhat generic algorithm to create such regexes. I posted a regex generator for a closely related problem to the fun-with-perl list a while ago. Since adapting it to your question would take more fiddling than I currently have the stamina for, I'll simply outline the structure of the resulting regex (written in /x syntax for the purposes of this post):

    0* (?: 1\d? | 2 (?: [0-4]\d? | 5[0-5]? ) ) (?: (?: # since we got here, the first 1-3 digits formed a number +< 256 # so allow a dot \. # a near-copy of the surrounding regex goes here to match +next octet ) | # no dot matched: allow digit-only strings forming numbers up +to 2**32-1 # (and remember we might already have matched up to 3 digits!) # this bit needs adjusting to smaller ranges in the nested cop +ies )

    You can see that it's highly formulaic.

    It might make an interesting project to generalize a few numeral-matching pattern builders sufficiently to make them into a module (if such a thing doesn't already exist). I've built such regexen by hand often enough that I've gotten thoroughly sick of doing it; it's a nearly trivial but mind numbingly tedious task.

    Makeshifts last the longest.

Re: (Golf) Expression for matching numeric IP addresses
by naChoZ (Curate) on Aug 10, 2004 at 12:26 UTC

    For some interesting reading on this topic, you should probably check out the Don't Use Regular Expressions To Parse IP Addresses! node. It's quite detailed and informative.

    --
    "A long habit of not thinking a thing wrong, gives it a superficial appearance of being right." -- Thomas Paine
    naChoZ