Match ip address using regex

Question:

I’m trying to match a simplified version of IP addresses (I believe this pattern should match all IP addresses and then some things that aren’t IP addresses, but that’s not really important.) I’m using this syntax in Python:

'([0-9]{1,3}.){3}[0-9]{1,3}'

This, however, matches “127.”, for example. As far as I can tell it’s interpreting what I’ve provided as a list of patterns rather than a single one. What am I missing?

UPDATE: Yes, sorry everyone, I had a typo. I fixed it.

Everyone is saying the pattern as-is works perfectly, but I’m not getting that. Maybe my issue lies elsewhere:

        matches = regex.findall(line)
        for match in matches:
            matchList.add(label + match)

If I use the pattern ‘(‘d{1,3}.d{1,3}.d{1,3}.d{1,3}’ instead (same thing, I just repeated, this works perfectly and gives a full IP address. However, if I use the pattern above, it instead gives ‘195.’

If I put a paren around this expression to get ‘((d{1,3}.){3}d{1,3})’, label + match gives me the error ‘cannot concatenate string and tuple objects’

Asked By: Jeremy

||

Answers:

try this

quoted from this :

def is_valid_ipv4(ip):
    """Validates IPv4 addresses.
    """
    pattern = re.compile(r"""
        ^
        (?:
          # Dotted variants:
          (?:
            # Decimal 1-255 (no leading 0's)
            [3-9]d?|2(?:5[0-5]|[0-4]?d)?|1d{0,2}
          |
            0x0*[0-9a-f]{1,2}  # Hexadecimal 0x0 - 0xFF (possible leading 0's)
          |
            0+[1-3]?[0-7]{0,2} # Octal 0 - 0377 (possible leading 0's)
          )
          (?:                  # Repeat 0-3 times, separated by a dot
            .
            (?:
              [3-9]d?|2(?:5[0-5]|[0-4]?d)?|1d{0,2}
            |
              0x0*[0-9a-f]{1,2}
            |
              0+[1-3]?[0-7]{0,2}
            )
          ){0,3}
        |
          0x0*[0-9a-f]{1,8}    # Hexadecimal notation, 0x0 - 0xffffffff
        |
          0+[0-3]?[0-7]{0,10}  # Octal notation, 0 - 037777777777
        |
          # Decimal notation, 1-4294967295:
          429496729[0-5]|42949672[0-8]d|4294967[01]dd|429496[0-6]d{3}|
          42949[0-5]d{4}|4294[0-8]d{5}|429[0-3]d{6}|42[0-8]d{7}|
          4[01]d{8}|[1-3]d{0,9}|[4-9]d{0,8}
        )
        $
    """, re.VERBOSE | re.IGNORECASE)
    return pattern.match(ip) is not None
Answered By: Abdul Kader

Is that slash before [0-9] a typo?

If so, if you add parenthesis around the whole expression '(([0-9]{1,3}.){3}[0-9]{1,3})' you’ll create a capture group that will capture the entire match. Otherwise you’re just capturing a part of your string.

Answered By: João Neves

Maybe you mistyped something when you posted but when I used your regex as posted, it didn’t match “127.” or “127.0.0.1”. When I removed the extraneous backslash, it seems to work fine for me

In [22]: re.match(r'([0-9]{1,3}.){3}[0-9]{1,3}', '127.0.0.1')
Out[22]: <_sre.SRE_Match object at 0x1013de5d0>

In [23]: re.match(r'([0-9]{1,3}.){3}[0-9]{1,3}', '127.')
Answered By: Marc Abramowitz

Quick answer, use this instead:

(?:[0-9]{1,3}.){3}[0-9]{1,3}

Long answer:

Using 127.0.0.1 as an example, the regex you posted will only match “0.” rather than the full address. The parentheses you’re using creates a matching group, which tells the parser to ensure that the entire pattern is found, but only return a match for what’s in the () group, which leaves you with “127.0.0.”. Plus regex is greedy by default and will automatically choose the furthest/last possible match. So with the {3} after the parentheses acting somewhat like an index in this case, you end up with the third match and therefore “0.”

A set of parentheses by themselves creates a matching group, but what you want instead is a non-matching group. Add a ?: just after the first parenthesis like I showed above to signify this. That way it will still return a match for the entire line. This should give you the “simplified” regex you’re looking for.

Answered By: epenn

These two regex expression written by my friends, worked on python, you can try these expressions.

  1. Matching the numbers in each ip session within 255.

^(?:(?:^|.)(?:1?d{1,2}|2[0-4]d|25[0-5])){4}$

  1. Matching the numbers in each ip session not beyond 255.

^(?!.*(25[6-9]|2[6-9]d|[3-9]dd)|d{4})d+.d+.d+.d+$

Both worked efficiently but in different ways.

Answered By: icychick
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.