logo VB.Net - Validatition & Regex
Guide Contents
DigitalDan Home Page

Validation
The functions on this page offer basic validation techniques for various problems. Some of the functions indicate that a value is "very plausible" rather than claiming 100% accuracy. An example of the is the UK postcode validator which detects most invalid postcodes and all postcodes with impossible formats. A perfect validator would have to lookup the entry in a list of over 2,000,000 valid postcodes and update this list whenver new postcodes are issued. Many of the examples use "Regular Expressions," these are a tool that quickly matches patterns of letters or numbers. I suspect many readers will only want to find a Function that will perform a task but advanced users will find additional Regex information at the end the page.
Plausible UK Postcode
Private Shared Function Is_UK_PostCode(postCode As String) As Boolean Dim postCodeRegEx As String
postCodeRegEx = "^(GIR ?0AA|[A-PR-UWYZ]([0-9]{1,2}|([A-HK-Y][0-9]([0-9ABEHMNPRV-Y])?)|[0-9][A-HJKPS-UW]) ?[0-9][ABD-HJLNP-UW-Z]{2})$"
Return System.Text.RegularExpressions.Regex.IsMatch(postCode, postCodeRegEx, System.Text.RegularExpressions.RegexOptions.IgnoreCase)
End Function

 
Plausible Email Address
Private Shared Function Is_Email_Address(txt As String) As Boolean
Dim emailRegex As New Text.RegularExpressions.Regex("^[_a-z0-9-]+(.[a-z0-9-]+)@[a-z0-9-]+(.[a-z0-9-]+)*(.[a-z]{2,4})$")
Return emailRegex.IsMatch(txt)
End Function

 
Plausible UK National Insurance Number
Private Shared Function Is_Plausible_UK_NI(txt as string) as Boolean
Dim niRegex As New Text.RegularExpressions.Regex("^(?!BG)(?!GB)(?!NK)(?!KN)(?!TN)(?!NT)(?!ZZ)(?:[A-CEGHJ-PR-TW-Z][A-CEGHJ-NPR-TW-Z])(?:\s*\d\s*){6}([A-D]|\s)$")
Return niRegex.IsMatch(txt)
End Function

 
Plausible UK Driving Licence Number
Private Shared Function Is_Plausible_UK_Driving(txt as string) as Boolean
Dim driveRegex As New Text.RegularExpressions.Regex("^[A-Z0-9]{5}\d[0156]\d([0][1-9]|[12]\d|3[01])\d[A-Z0-9]{3}[A-Z]{2}$")
Return driveRegex.IsMatch(txt)
End Function

 
Plausible Credit Card Number
Almost all credit card issuers use a check digit based on the "Luhn" algorhythmn. Although not impossible, it is very unusual to encounter valid credit cards disobeying Luhn and intended for western market transactions. The Luhn function will reliably detect adjacent digits that are reversed or a single wrong digit. (The error detection rate for numbers entered with multiple errors is about 90%.) Most credit card numbers have exactly 16 digits but the number of digits can vary from 12 digits to 19 digits.
 
This function performs basic validation by combining simplified checks with with Luhn. However, commercial systems should employ a more robust validation procedure. Notice that the credit card number is entered as a text string, (which should only contain numeric digits.) A 19 digit card number could cause a long integer to overflow and string-based logic is easier to understand.
 

 
Private Shared Function Is_Plausible_Card(number As String) As Boolean
' Remove any spaces, some cards use spaces to make numbers easier to read
' but Credit Card numbers can only include teh digits 0 to 9
number = number.Replace(" "c, "")
'
' Credit card numbers can only contain digits. All other characters are invaild
Dim regex As New Text.RegularExpressions.Regex("^[0-9]")
If Not regex.IsMatch(number) Then
Return False
End If
'
' Simplified length check
' A full check would check Card Issuer code (first few digits) and
' establish which card number lengths are used by the specific issuer
If number.Length < 12 Or number.Length > 19 Then
Return False
End If
'
' Luhn validation
Dim doubleIt As Boolean = False
Dim digit As Integer
Dim total As Integer = 0
For i As Integer = number.Length To 1 Step -1
digit = CInt(Val(Mid(number, i, 1)))
If doubleIt Then
total += digit * 2
If digit > 4 Then
total += 1
End If
Else
total += digit
End If
doubleIt = Not doubleIt
Next
Return (total Mod 10 = 0)
End Function

 
Plausible UK Phone Number
Private Shared Function Is_Plausible_UK_Phone(txt As String) As Boolean
If txt = "" Then Return True ' User can leave number blank
' we cannot validate international calls
If Len(txt) > 2 Then
If Mid(txt, 1, 2) = "00" Then
Return (Len(txt) > 9)
End If
End If
If Len(txt) < 3 Then Return False
If Mid(txt, 1, 3) = "000" Then Return False
Dim txt2 As String = "#" & txt & "#"# Dim test As String = "#100#101#105#101#111#112#119#123#141#155#999#1470#1471#1472#1474#1475#1476#1477#1478#1479#1571#1572#17070#08001111#"
If test.Contains(txt2) Then Return True
If Len(txt) = 6 Then
If ((Mid(txt, 1, 3) = "116") OrElse (Mid(txt, 1, 3) = "118")) Then Return True Else Return False
End If
If Len(txt) = 8 Then
If Mid(txt, 1, 7) = "0845464" Then Return True Else Return False
End If
If Len(txt) = 10 Then
If ((Mid(txt, 1, 2) = "01") Or (Mid(txt, 1, 4) = "0800")) Then Return True Else Return False
End If
If Len(txt) = 11 Then
If Mid(txt, 1, 2) = "01" Then Return True
If Mid(txt, 1, 2) = "02" Then Return True
If Mid(txt, 1, 2) = "03" Then Return True
If Mid(txt, 1, 2) = "04" Then Return False
If Mid(txt, 1, 3) = "055" Then Return True
If Mid(txt, 1, 3) = "056" Then Return True
If Mid(txt, 1, 2) = "05" Then Return False
If Mid(txt, 1, 2) = "06" Then Return False
If Mid(txt, 1, 2) = "07" Then Return True
If Mid(txt, 1, 2) = "08" Then Return True
If Mid(txt, 1, 2) = "09" Then Return True
Return True
End If
Return False
End Function

 
Likely to be a Premium Rate Phone Number
Private Shared Function Premium_Rate__Number(txt As String) As Boolean
' this routine is not foolproof - e.g it may not handle any new premium rate
' number blocks
Dim txt2 As String
Dim test As String
If txt = "" Then Return False
If Len(txt) >= 2 Then
txt2 = "#" & Mid(txt, 1, 2) & "#"
test = "#00#09#"
' 00 = international
' 09 = standard premium rate number block
If test.Contains(txt2) Then Return True
End If
If Len(txt) >= 3 Then
txt2 = "#" & Mid(txt, 1, 3) & "#"
test = "#070#076#055#056#084#087#100#118#101#"
If test.Contains(txt2) Then Return True
' personal numbers, special connections and specialist numbers
End If
If Len(txt) >= 4 Then
txt2 = "#" & Mid(txt, 1, 4) & "#"
test = "#0820#08999#"
If test.Contains(txt2) Then Return True
' Specialist numbers
End If
If Len(txt) >= 5 Then
txt2 = "#" & Mid(txt, 1, 5) & "#"
test = "#01481#01534#07781#07839#07911#07509#07797#01624#07624#07524#07924#"
If test.Contains(txt2) Then Return True
' Guersey, Man, Guernsey etc. Expensive under some phone contracts
End If
If Len(txt) >= 6 Then
txt2 = "#" & Mid(txt, 1, 6) & "#"
test = "#079112#079118#07937#07700#07829#"
If test.Contains(txt2) Then Return True
' Personal numbers, ofshore island mobile etc.
End If
Return False
End Function

 

Replace a Pattern of Characters in String Using Regex
Private Function Regex_Replace(textIn As String, reg As String, replaceWith As String) As String
' This function examines textIn and replaces all matches of the regularexpression... reg
Dim regularEx As New Text.RegularExpressions.Regex(reg)
Dim txt As String
txt = regularEx.Replace(textIn, replaceWith)
Return txt
End Function

 
Find a Pattern of Characters in String Using Regex
' will return -1 if no match
' will return 0 based index showing position of first match if found
Dim regularEx As New Text.RegularExpressions.Regex(reg)
Dim mat As Text.RegularExpressions.Match = regularEx.Match(textToSearch)
If mat.Success Then
Return mat.Index
End If
Return -1

 
Sample of Codes Used with Regex Patterns
/tMatches a tab
/rMatches a carriage return
[abc]Matches any character in box (case-sensitive)
[^ ]Matches any character that is not in box
$Only matches if match ends at last character of string
^(When not in box) Only matches if match starts in first character of string
[a-z]Matches any character in the range a to z
.Matches any character except newline
\dMatches any decimal digit (same as [0-9])
\DMatches any character that is not a decimal digit (same as [^0-9])
\GOnly matches if match occurs at the same position that the last match ended
*Matches previous secrion zero or more times
+Matches the previous section one or more times
?Matches the previous section zero or one time
?(If following {...} * + or ?) Match the minimum number of times to obey any other regex requirements
{5}Matches the previous element exactly 5 times
{6,}Matches the previous element at least 6 times
{7,9}Matches the previous element between 7 times and 9 times

DigitalDan.co.uk ... Hits = 165