Eldin
Eldin

Reputation: 11

How to verify that user input is in the correct format in python

I'm trying to make a script in python and I need to verify that the user input is in the correct format, like 000.000 or 00.0 or any other combination of the first 2 segments of an IP (0 can be any digit).

I have tried using the metacharacter "|" and the special sequence "\d" from the re module to make all the possible combinations but now even if I type something like 14576.2345 it is marked as correct user input.

import re

ip_class = input("Enter ip class: ")

def ip_range(ip_start):
    pattern= r"(\d+\d+\d+.+\d+\d+\d|\d+\d+.+\d+\d|\d+.+\d|\d+\d+\d+.+\d+\d|\d+\d+\d+.+\d|\d+\d+.+\d+\d+\d|\d+.+\d+\d+\d|\d+\d+.+\d|\d+.+\d+\d)"
    match = re.match(pattern, ip_start)
    if match:
        print ("it works")
    else:
        print ("it doesnt work")

ip_range(ip_class)

I expect that if I type somthing that can't be the first 2 segments of an ip like 234534.1345 it would say "It doesn't work" but it says "it works" It says it works to every number that is at least 3 digits long even without the period.

Upvotes: 1

Views: 88

Answers (2)

Yann Vernier
Yann Vernier

Reputation: 15887

import socket
somestr = '123.0xe0f'
try:
    addr = socket.inet_aton(somestr)
except OSError as e:
    raise    # String was not an inet address

This is a case where it's far easier to check for failure than guess. There may be quite a few more valid formats than you expect. Also, . is a wildcard in regular expressions.

You could also use socket.inet_pton(socket.AF_INET, somestr) if you want specifically the quad-dotted notation. That is also expressible as an overly complex regular expression.

Edit: My sloppy reading somehow skipped over "first 2 segments". I suppose one way to do that is to append ".0.0" for this check, though that still allows either one or two segments.

Regular expressions are not ideal for bound checking numbers. For instance, a non-zero-prefixed decimal number from 0 to 255 might be \d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]. Now consider how clear it will be to the next reader of the code not only what a regular expression containing at least two such groups is intended to check, but also that it does it correctly.

Upvotes: 3

user9117353
user9117353

Reputation:

Here it goes.

import re

ip_class = input("Enter ip class: ")

def ip_range(ip_start):
    pattern= r"(\d{3}.\d{3})"
    match = re.match(pattern, ip_start)
    if match:
        a = ip_class.split(".")

        for b in a:
            if int(b) not in range(0,256):
                print ("it doesnt work")
                return
        print ("it works")
    else:
        print ("it doesnt work")

ip_range(ip_class)

Upvotes: 0

Related Questions