# re Challenge: More Compact?

Tim Peters tim.one at home.com
Sun Jul 15 21:36:22 EDT 2001

```[Tim Hammerquist]
> ...
> Easily implemented in Perl:
>
>: sub valid_ip {
>:     my (\$ip, \$failed, @elements) = (shift, 0);
>:     @elements = (\$ip =~ /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\$/);
>:     \$failed = grep { \$_ > 255 } @elements;
>:     return (\$failed) ? undef : 1;
>: }
>
> Slightly more verbose in Python:
>
>: import re
>: def valid_ip(ip):
>:     expr = r'^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\$'
>:     elements = map(int, re.match(expr, ip).groups())
>:     failed = filter(lambda x: x > 255, elements)
>:     if failed:  return None
>:     else:       return 1

Well, it's un-Pythonic to try to emulate Perl undef via Python None; it's
idiomatic to return 0 for false and 1 for true, in which case the last three
lines can be replaced by, e.g.,

return max(elements) < 256

Note that the leading "^" in the Python regexp isn't needed (can save
another entire character that way <wink>).

The Python version should also check for match failure.  Like

def valid_ip(ip):
m = re.match(r'(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\$', ip)
if m:
elements = map(int, m.groups())
return max(elements) < 256
return 0

Yes, you can squash lines out of that -- I wouldn't.

BTW, does it bother anyone that all of these solutions accept an IP ending
with a newline?

regexps-are-surprising-ly y'rs  - tim

```