0

I'm working on a project that aims to collect a group of the best IPv6 address validation regexes. The biggest issue I have is I'm not amazing at regex.

The issue with IPv6 is that its notation is hugely variable. This means that while a regex might work for your use case it might miss other corner cases. In this instance I only want to match IPv6 addresses but not their CIDR notation cousins.

So my questions are:

  • What is the best IPv6 address (non CIDR) validation REGEX you know of?
  • What are your favourite/the most difficult corner cases you've found?

I'm not looking for a library to use in this instance - I just want the regex.

Test Cases

Here are the valid/invalid test cases I've collected so far:

Regex Attempts

This is a collection of the regexes I've collected so far but all of them so far miss test cases like IPv4 in IPv6 addressing notation or they match on invalid addresses as well.

Attempt 1 - Misses IPv4 in IPv6

^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$

Attempt 2 - Misses too many tests to list

^(?:[A-f0-9]{1,4}:){7}[A-f0-9]{1,4}|(?=(?:[A-f0-9]{0,4}:){2,8}(?::\d{1,3}\.){3}\d{1,3}$)(([0-9a-fA-F]{1,4}(:)){1,6}|:(:[0-9a-fA-F]{1,4}(:)){1,5}|((([0-9a-fA-F]{1,4}:){1,6})|((:[0-9a-fA-F]{1,4}){1,6}))(?:(:\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})|(?:\/\d\d?)|\b|$))$

Attempt 3 - Misses addresses ending in ::

^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$

Attempt 4 - Misses IPv4 in IPv6 & notations that include the interface name, matches on many invalid addresses, part matches strings

(([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4})

Attempt 5 - Misses addresses with zone indexes, matches some invalid addresses

(?:^|(?<=\s))(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))(?=\s|$)

Thank you for sharing your knowledge and experience!

  • [This answer](https://stackoverflow.com/a/74503707/3745413) has a regular expression that handles all the valid IPv6 address formats (expanded, expanded-mixed, compressed, and compressed-mixed). It includes an optional prefix length at the end that could easily be removed should you not want it. CIDR (_Classless_ Inter-Domain Routing) is actually an IPv4 term because IPv6 has never had address classes the way IPv4 has. – Ron Maupin Mar 17 '23 at 11:22
  • 1
    Does this answer your question? [Regular Expression (RegEx) for IPv6 Separate from IPv4](https://stackoverflow.com/questions/21631669/regular-expression-regex-for-ipv6-separate-from-ipv4) – Ron Maupin Mar 17 '23 at 11:37
  • Hey Ron - unfortunately that regex doesn't work for me. I'm not sure what environment you're using this in but the regex tool I tested with had all the usual suspects. I have even tried removing comments from it and the only matches I get when messing around with it a lot are things I shouldn't be matching. – David Hooton Mar 21 '23 at 12:54
  • The tool I use to help me create and test is [RegexBuddy](https://www.regexbuddy.com/). You can use it to format the regular expression and create the code to use it in a large variety of programming languages. It works for me as you can see in [the IPvX IP calculator](https://github.com/rmaupin/IPvX). – Ron Maupin Mar 21 '23 at 16:02

0 Answers0