const reg = /^(?=.*[A-Z].*[A-Z])(?=.*\d.*\d)\w{5,20}$/
reg.test('AAgata01'); //true
reg.test('A0gata1A'); //true
reg.test('0aG1aTa1ag0X'); //true
reg.test('Agata1'); //false
Przykład w JavaScript, bo w PHP już wieki nie pracowałem ale sam regexp będzie taki sam.
Generalnie to składa się on z kilku części:
/^ //początek analizowanego ciągu znakowego
(?=.*[A-Z].*[A-Z]) //w ciągu muszą być dwie wielkie litery A-Z
(?=.*\d.*\d) //w ciągu muszą być dwie cyfry 0-9
\w //cały ciąg może składać się ze znaków A-Za-z0-9_
{5,20} //długość ciągu to od 5 do 20 znaków
$/ //koniec analizowanego ciągu
Dostosuj sobie tylko dwa ostatnie parametry, czyli znaki dopuszczone w haśle oraz jego długość.
Pamiętaj też o obowiązkowym wskazaniu granicy początku i końca ciągu!
Jakby co to pisz, a jak coś nie działa to daj przykładowe dane, na których się wywalają testy.