Guess 1
My guess is that, maybe
^(?!.*[a-z]{2}|.*[0-9]{2})[a-z0-9]{3,5}$
or
^(?!.*(?:[a-z]{2}|[0-9]{2}))[a-z0-9]{3,5}$
might be desired, if two consecutive letters or digits wouldn't be allowed.
Guess 2
If we want to at least have a letter and a digit:
^(?=.*[a-z])(?=.*[0-9])[a-z0-9]{3,5}$
might be an option.
Guess 3
If any 3 to 5 times letters or digits are allowed:
^[a-z0-9]{3,5}$
might just work fine.
Test
import re
string = '''
aaa
aaa1
aaab1
a1
a1b2
a1b2c3
a1b2c3d4
'''
expression = r'^(?=.*[a-z])(?=.*[0-9])[a-z0-9]{3,5}$'
print(re.findall(expression, string, re.M))
Output
['aaa1', 'aaab1', 'a1b2']
If you wish to simplify/modify/explore the expression, it's been explained on the top right panel of regex101.com. If you'd like, you can also watch in this link, how it would match against some sample inputs.
RegEx Circuit
jex.im visualizes regular expressions:
![enter image description here]()