I’m trying to get the Xojo Regex to detect IPv6 addresses but just cannot get it to work. I have IPv4 working and the IPv6 pattern I’m trying works in other languages. Below is the code I’m trying. A solution would be very appreciated.
Dim rg as New RegEx
dim rgm as RegExMatch
rg.SearchPattern = "/^(((?=.*(::))(?!.*\\3.+\\3))\\3?|([\\dA-F]{1,4}(\\3|:\\b|$)|\\2))(?4){5}((?4){2}|(((2[0-4]|1\\d|[1-9])?\\d|25[0-5])\\.?\\b){4})\\z/i" // PCRE pattern
// rg.SearchPattern = "/^(((?=.*(::))(?!.*\\3.+\\3))\\3?|([\\dA-F]{1,4}(\\3|:\\b|$)|\\2))(?4){5}((?4){2}|(((2[0-4]|1\\d|[1-9])?\\d|25[0-5])\\.?\\b){4})\\z/ai" // Perl pattern
rgm = rg.Search(txtPing1.Text)
if rgm <> nil then MsgBox "ipv6"
I wrote a quick demo for you to match IPv6 address. The regular expression matching is done via a function I wrote to return an Array of matched IPv6 Addresses.
Private Function fMatchIPV6(inStringtoProcess as String) As String()
Dim MatchIPv46_RegEx as RegEx
Dim MatchIPv46_RegExMatch as RegExMatch
Dim MatchIPv46_HitText as String
Dim MatchIPv46_Array() As String
Dim Counter as Integer
MatchIPv46_RegEx = New RegEx
MatchIPv46_RegEx.Options.Greedy = True
MatchIPv46_RegEx.Options.CaseSensitive = False
MatchIPv46_RegEx.Options.MatchEmpty = True
MatchIPv46_RegEx.Options.DotMatchAll = True
MatchIPv46_RegEx.Options.StringBeginIsLineBegin = True
MatchIPv46_RegEx.Options.StringEndIsLineEnd = True
MatchIPv46_RegEx.Options.TreatTargetAsOneLine = False
MatchIPv46_RegEx.SearchPattern = "^(?>(?>([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}))$"
MatchIPv46_RegExMatch = MatchIPv46_RegEx.Search(inStringtoProcess)
// This will match any IPv6 address and then continue to look for matches
While MatchIPv46_RegExMatch <> Nil
MatchIPv46_HitText = MatchIPv46_RegExMatch.SubExpressionString(0)
MatchIPv46_Array.Append MatchIPv46_HitText+EndOfLine
MatchIPv46_RegExMatch = MatchIPv46_RegEx.Search
Wend
Return MatchIPv46_Array()
End Function
I updated the Dropbox project and here is the updated code. I noticed that I was missing some matches because I wasn’t taking the input string and converting it to an input array prior to matching.
Private Function fMatchIPV6(inStringtoProcess as String) As String()
Dim MatchIPv46_RegEx as RegEx
Dim MatchIPv46_RegExMatch as RegExMatch
Dim MatchIPv46_HitText as String
Dim InStringArray() as String
Dim MatchIPv46_Array() As String
Dim Counter as Integer
InStringArray() = Split(inStringtoProcess,EndOfLine)
MatchIPv46_RegEx = New RegEx
MatchIPv46_RegEx.Options.Greedy = True
MatchIPv46_RegEx.Options.CaseSensitive = False
MatchIPv46_RegEx.Options.MatchEmpty = True
MatchIPv46_RegEx.Options.DotMatchAll = True
MatchIPv46_RegEx.Options.StringBeginIsLineBegin = True
MatchIPv46_RegEx.Options.StringEndIsLineEnd = True
MatchIPv46_RegEx.Options.TreatTargetAsOneLine = False
MatchIPv46_RegEx.SearchPattern = "^(?>(?>([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}))$"
for i as integer = 0 to UBound(InStringArray)
MatchIPv46_RegExMatch = MatchIPv46_RegEx.Search(InStringArray(i))
// This will match any IPv6 address and then continue to look for matches
While MatchIPv46_RegExMatch <> Nil
MatchIPv46_HitText = MatchIPv46_RegExMatch.SubExpressionString(0)
MatchIPv46_Array.Append MatchIPv46_HitText+EndOfLine
MatchIPv46_RegExMatch = MatchIPv46_RegEx.Search
Wend
Next i
Return MatchIPv46_Array()
End Function
I haven’t looked at either, but the pattern in a Xojo RegEx object should not start with a delimiter like “/”. Anything in the SearchPattern will be matched.
The same goes for an ending delimiter and the options after it. Use RegEx.Options to set your options.
I appreciate the two solutions but neither detects all IPv6 possibilities. I tried a bunch of tests and a lot of them got matched but I’ll give two examples that didn’t get matched (but do in other languages).
Mike, I guess you did what I just did: Pasted both the valid and invalid addresses into RegExRX to make sure your pattern matched the former and not the latter.