I’m trying to confirm that a password contains at least one Capital Letter and One Number. The following search pattern works when it finds a number, but isn’t catching the lack of capital letter.
Hi @Jean-Yves_Pochez , the funny thing is that is the exact expression I started the post with that didn’t work. Here is a more detailed look (at the non-working expression):
Var rg As New RegEx
Var myMatch As RegExMatch
rg.SearchPattern = "^(?=.*[A-Z])(?=.*\d).+$"
myMatch = rg.Search(new_pwd)
If myMatch <> Nil Then
System.DebugLog(CurrentMethodName + " OK")
Else
System.DebugLog(CurrentMethodName + " NOT GOOD")
End If
As a non-Regex alternative (for others reading this post?), I wrote this Method to check not only that the password contains a number and uppercase/lowercase, but contains more than X letters and the confirmation password are identical:
Protected Function getCheckPasswords(password1 As String, password2 As String, minLength As Integer = 8, mustContainUpperLowercase As Boolean = True, mustContainNumber As Boolean = True) As String
'test main password
If password1.Length < minLength Then Return "Password must be at least " + minLength.ToString + " characters"
If mustContainUpperLowercase And CommonStrings.isSameCaseWAD(password1, password1.Lowercase) Then
Return "Password must contain upper and lowercase"
End If
If mustContainNumber And _
password1.IndexOf("0") < 0 And _
password1.IndexOf("1") < 0 And _
password1.IndexOf("2") < 0 And _
password1.IndexOf("3") < 0 And _
password1.IndexOf("4") < 0 And _
password1.IndexOf("5") < 0 And _
password1.IndexOf("6") < 0 And _
password1.IndexOf("7") < 0 And _
password1.IndexOf("8") < 0 And _
password1.IndexOf("9") < 0 Then
Return "Password must contain at least one number"
End If
If password2 = "" Then Return "Please enter Confirm Password"
'test Confirm Password
If password2.Length < minLength Then Return "Confirm Password must be at least " + minLength.ToString + " characters"
If mustContainUpperLowercase And CommonStrings.isSameCaseWAD(password2, password2.Lowercase) Then
Return "Confirm Password must contain upper and lowercase"
End If
If mustContainNumber And _
password2.IndexOf("0") < 0 And _
password2.IndexOf("1") < 0 And _
password2.IndexOf("2") < 0 And _
password2.IndexOf("3") < 0 And _
password2.IndexOf("4") < 0 And _
password2.IndexOf("5") < 0 And _
password2.IndexOf("6") < 0 And _
password2.IndexOf("7") < 0 And _
password2.IndexOf("8") < 0 And _
password2.IndexOf("9") < 0 Then
Return "Confirm Password must contain at least one number"
End If
If Not CommonStrings.isSameCaseWAD(password1, password2) Then Return "Both Passwords must be the same"
Return ""
End Function
As @Greg_O alluded, the default setting for Xojo’s RegEx is case-insensitive. You can use his recommendation or put a switch directly into the pattern.
(?-i)^(?=.*[A-Z]) ...
Two things: your plan doesn’t ensure that there is a lowercase letter present so even when it’s working, “ABC123” would pass. And it doesn’t take into account anything other than English capitals.
Assuming you want to rectify both of these issues, this is how I’d write it:
^(?=.*\p{Lu})(?=.*\p{Ll})(?=.*\d).*
\p{type} is for identifying unicode. Lu means “uppercase” and Ll is lowercase.
var rx as new RegEx
var tx as string = "Abbc1"
rx.SearchPattern = "(\p{Lu})(?=.*\d)"
if rx.Search( tx ) isa RegExMatch then
msgbox "has uppercase and 1 number"
else
msgbox "not"
end if
David, in your non-regex solution you are testing both the initial password and the confirm password for the same criteria. But - the confirm password must just match the initial password. So there is not need to test it other than it matches the initial password that is only valid if it passes the criteria.
You might say, “…but the user can put data in the confirm password field first.” I’d just test for that - disallow the confirm entry until a valid entry is in the initial pw field.