Please read before marking as duplicate
I have not been able to create or find a RegEx that works for all IPv6 formats (my test cases are below). I am aware of this question that everyone points to: Regular expression that matches valid IPv6 addresses However, They all combine IPv6 with IPv4 and/or do not work with all my test cases.
Requirements:
- I do not want it to also validate IPv4 values, I already have a separate validation function for IPv4.
- I need a pattern that works in
Coldfusion
and a pattern that works in PL/SQL
.
- Because I'm using it in
PL/SQL
the pattern for it must stay under 512 characters. And Oracle supports only a narrow part of RegExp language. So the ColdFusion
pattern could end up being different than the PL/SQL
pattern, that is fine, so long as they both work.
- End result doesn't have be one long RegEx, it can be split up.
Here is the latest pattern I'm trying out:
^(?>(?>([a-f0-9]{1,4})(?>:(?1)){7}|(?!(?:.*[a-f0-9](?>:|$)){8,})((?1)(?>:(?1)){0,6})?::(?2)?)|(?>(?>(?1)(?>:(?1)){5}:|(?!(?:.*[a-f0-9]:){6,})(?3)?::(?>((?1)(?>:(?1)){0,4}):)?)?(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(?>.(?4)){3}))$
This comes close for ColdFusion
but not 100%. It doesn't work at all in PL/SQL
.
Test Results http://regex101.com/r/wI8cI0 The bold items are the ones the pattern doesn't work for in ColdFusion
:
- match
- match
- match
- match
- match
- match (but @Michael Hampton says this should not match because it's not a valid IPv6 address, but others have told me it is valid, so I'm not sure about this test case.)
- match (
::
is actually a valid format, thanks @Sander Steffann.)
- match
- no match
- match
- no match
- no match
- no match
- match
- match
- no match
- no match
- no match
- no match
I got test cases 8-11 from: http://publib.boulder.ibm.com/infocenter/iseries/v5r3/index.jsp?topic=%2Frzai2%2Frzai2ipv6addrformat.htm
And was told: Test 9 and 11 are for IPv6 address prefix, not an IPv6 address, so those should not be match.
End result, I need them to work in statements like this:
ColdFusion:
<cfset IndexOfOccurrence1=REFind("^(?>(?>([a-f0-9]{1,4})(?>:(?1)){7}|(?!(?:.*[a-f0-9](?>:|$)){8,})((?1)(?>:(?1)){0,6})?::(?2)?)|(?>(?>(?1)(?>:(?1)){5}:|(?!(?:.*[a-f0-9]:){6,})(?3)?::(?>((?1)(?>:(?1)){0,4}):)?)?(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(?>.(?4)){3}))$",value[i])>
PL/SQL:
if ( REGEXP_LIKE(v,'^(?>(?>([a-f0-9]{1,4})(?>:(?1)){7}|(?!(?:.*[a-f0-9](?>:|$)){8,})((?1)(?>:(?1)){0,6})?::(?2)?)|(?>(?>(?1)(?>:(?1)){5}:|(?!(?:.*[a-f0-9]:){6,})(?3)?::(?>((?1)(?>:(?1)){0,4}):)?)?(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(?>.(?4)){3}))$','i') ) then
See Question&Answers more detail:
os