0

I am currently trying to script a task for my Bind9 server. The goal is to have the user input an IP address in the following format:

192.168.90.150

I would then like Python to take that IP address and dissect it into 4 different groupings in 4 different variables

192.168.90.150 would become...

first  = 192 
second = 168
third  = 90
fourth = 150

I assume the "industry standard" way of doing this would be with regular expressions. I have tried to use the following search strings to identify groupings of 1-3 numeric characters separated by periods. The following didn't work.

ipaddy = raw_input('Enter IP address: ')

failsearch1 = re.search(r'\d+\.')
failsearch2 = re.search(r'\d\.')
failsearch3 = re.search(r'(\d)+\.')

for x in ipaddy:
    a = search.failsearch1(x)
    b = search.failsearch2(x)
    c = search.failsearch3(x)
    if a or b or c:
        print('Search found')

The output of the code above is nothing.

I've also tried several other variants of these search strings. Does anyone have any ideas how I can turn a typical IP address (192.168.10.10) into 4 different groupings based on separation between periods?

Any advice would be appreciated. Thanks.

Jorge
  • 31
  • 2
  • 8
  • 2
    Why not just split on a `.`, that would give you an array – Hunter McMillen Jul 21 '12 at 14:36
  • 1
    Agreed that it's more trouble than it's worth to do it with a regex. Split them by a `.` and check that they're numbers between 0 and 255. If you want a reference, I've posted a Javascript version here: https://gist.github.com/2649187 – bcoughlan Jul 21 '12 at 14:38
  • @bcoughlan I'm going to use that snippet in my code if you don't mind..? – D.Tate Jun 26 '14 at 22:00
  • @D.Tate Not a problem, I always assumed Gists were under some public domain license... – bcoughlan Jun 27 '14 at 14:31
  • @bcoughlan thx a lot, yeah beats me, sometimes I like to just check with the author anyway – D.Tate Jun 27 '14 at 15:59

5 Answers5

3

Validation: How to validate IP address in Python?

+plus

first, second, third, fourth = str(ipaddy).split('.')

Community
  • 1
  • 1
StefanNch
  • 2,569
  • 24
  • 31
3

If you are reasonably sure the input is going to be an IPv4 in dotted form, you don't even need a regular expression:

assert possible_ip.count(".") == 3
ip_parts = possible_ip.split(".")
ip_parts = [int(part) for part in ip_parts]
first, second, third, fourth = ip_parts
Sean Vieira
  • 155,703
  • 32
  • 311
  • 293
  • 1
    Shouldn't the assertion be `== 3` ? – Jon Clements Jul 21 '12 at 14:42
  • @Jon Yes it should be, although I'd rewrite it to assert `len(ip_parts) == 4` because that's more intuitive. – Voo Jul 21 '12 at 14:47
  • One liner: `first, second, third, fourth = [part for part in map(int, possible_ip.split(".")) if part < 255]` If it throws an exception it's invalid. – Steven Rumbalski Jul 21 '12 at 17:50
  • @StevenRumbalski - true - I like to split up the parts when answering questions that I might otherwise put on one line to help make walking through it easier :-) But good point! – Sean Vieira Jul 21 '12 at 18:07
1

You can just use the builtin str functions.

try:
    first, second, third, fourth = [int(s) for s in some_text.split('.')]
except ValueError as e:
    print 'Not 4 integers delimited by .'
if not all (0 <= i <= 254 for i in (first, second, third, fourth)):
    print 'Syntax valid, but out of range value: {} in "{}"'.format(i, some_text)
Jon Clements
  • 138,671
  • 33
  • 247
  • 280
0
def validate_and_split_ip(ip):
    parts = ip.split('.')
    if len(parts) != 4:
        return None

    for part in parts:
        if not part.isdigit() or not 0<=int(part)<=255:
            return None
    return [int(part) for part in parts]

Test:

>>> validate_and_split_ip('123.123.0.255')
[123, 123, 0, 255]
>>> validate_and_split_ip('123.123.0.256') # Returns None
>>> validate_and_split_ip('123.123.123.a') # Returns None

You then have a list rather than 4 variables, which is more Pythonic and cleaner.

bcoughlan
  • 25,987
  • 18
  • 90
  • 141
0


Make a list of bytes:

>>> [ byte for byte in '192.168.90.150'.split('.') ]
['192', '168', '90', '150']
Zulu
  • 8,765
  • 9
  • 49
  • 56