-1

I am trying to build an IPv4 regex in Python. This is what I have:

r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}'

And these are the inputs it misclassified:

Input: "172.316.254.1"
Output: true
Expected Output: false

Input: "1.1.1.1a"
Output: true
Expected Output: false

Input: "1.23.256.255."
Output: true
Expected Output: false

Input: "64.233.161.00"
Output: true
Expected Output: false

Input: "64.00.161.131"
Output: true
Expected Output: false

Input: "01.233.161.131"
Output: true
Expected Output: false

Input: "1.1.1.1.1"
Output: true
Expected Output: false

Input: "1.256.1.1"
Output: true
Expected Output: false

Input: "1.256.1.1"
Output: true
Expected Output: false

Input: "255.255.255.255abcdekjhf"
Output: true
Expected Output: false

This is the code that I have. It basically returns a boolean value:

import re

def isIPv4Address(inputString):
    pattern = re.compile(r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}')
    
    return pattern.match(inputString) is not None
Onur-Andros Ozbek
  • 2,998
  • 2
  • 29
  • 78

1 Answers1

0

The failing tests seem to have two causes:

  1. Matching first part of string.
  2. Not checking number format and value.

Matching first part of string

The test below fails because the first part of the string (1.1.1.1) matches your regex. The additional a does not change that:

Input: "1.1.1.1a"
Output: true
Expected Output: false

This happens because match returns an object when the first part of the string matches. From the docs:

If zero or more characters at the beginning of string match this regular expression, return a corresponding match object.

Use fullmatch if you only want an object when the whole string matches. From the docs:

If the whole string matches this regular expression, return a corresponding match object. Return None if the string does not match the pattern; note that this is different from a zero-length match.

Alternatively, you can append $ to your original regex to match the end of line/string. E.g., r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$'

Number format and value

The test below fails because your regex does not check the number's format or value. \d{1,3} only checks if there are between 1 and 3 digits. This matches all values from 000 to 0 to 9 to 999.

Input: "01.233.161.131"
Output: true
Expected Output: false

Checking if the value is within 0 and 255 can be done using a regex, but requires significantly expanding your current regex. See this answer as an example.

Jesse
  • 315
  • 2
  • 8