While setting up a Grav CMS website, a stronger username and password regex was in order. The username default regex for the installation is ^[a-z0-9_-]{3,16}$ all lower case letters, digits, dashes, underscores, and must be 3–16 characters. The default password regex is (?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,} one number, one upper case, one lower case, and 8 or more characters.
Username: ^[a-z0-9_-]{3,16}$
Password: (?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,}
The defaults are simply unacceptable. Too many websites are being hacked, and making a stronger regex is a simple way to make it harder to for the basement hacker to crack.
So, I did a bit of research, fed my requirements into my handy know-it-all (AI), tested it out, and voilà — a shinny new regex is born. 🙂
The Final Regex Code
Username:
^[a-z][a-z0-9_-]{4,16}$
Password:
^[a-z](?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?!.*(.)(\1))(?!.*0[oO]|.*[oO]0)(?!.*1[lLI]|.*[lLI]1)(?!.*5[sS]|.*[sS]5)(?!.*2[zZ]|.*[zZ]2)(?!.*8[bB]|.*[bB]8)(?!.*6[gG]|.*[gG]6)(?!.*9[gG]|.*[gG]9)(?!.*c[CƆ]|.*[CƆ]c)(?!.*a[@A]|.*[@A]a)(?!.*m.rn|.*rn.*m).{11,}$
The only difference in the regex codes above is the username must be 5–15 characters long, and the password must be at least 12 characters.
And for all the code junkies out there who stumble across this post, here are the technical bits:
Regex Breakdown
Username Regex:
^[a-z][a-z0-9_-]{2,15}$
| Component | Purpose |
|---|---|
^ | Start of string anchor |
[a-z] | Username must start with a lowercase letter |
[a-z0-9_-]{2,15} | Remaining characters must be lowercase letters, digits, underscores, or dashes Ensures total length is 3–16 characters |
$ | End of string anchor |
Password Regex:
^[a-z](?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?!.*(.)(\1))(?!.*0[oO]|.*[oO]0)(?!.*1[lLI]|.*[lLI]1)(?!.*5[sS]|.*[sS]5)(?!.*2[zZ]|.*[zZ]2)(?!.*8[bB]|.*[bB]8)(?!.*6[gG]|.*[gG]6)(?!.*9[gG]|.*[gG]9)(?!.*c[CƆ]|.*[CƆ]c)(?!.*a[@A]|.*[@A]a)(?!.*m.rn|.*rn.*m).{11,}$
| Component | Purpose |
|---|---|
^ | Start of string |
[a-z] | Password must start with a lowercase letter |
(?=.*[a-z]) | Requires at least one lowercase character |
(?=.*[A-Z]) | Requires at least one uppercase character |
(?=.*\d) | Requires at least one number |
(?!.*(.)(\1)) | No identical consecutive characters |
| Confusable (homoglyph) detection | |
(?!.*0[oO]|.*[oO]0) | Forbid 0 with o/O |
(?!.*1[lLI]|.*[lLI]1) | Forbid 1 with l/L/I |
(?!.*5[sS]|.*[sS]5) | Forbid 5 with s/S |
(?!.*2[zZ]|.*[zZ]2) | Forbid 2 with z/Z |
(?!.*8[bB]|.*[bB]8) | Forbid 8 with b/B |
(?!.*6[gG]|.*[gG]6) | Forbid 6 with g/G |
(?!.*9[gG]|.*[gG]9) | Forbid 9 with g/G |
(?!.*c[CƆ]|.*[CƆ]c) | Forbid c with C/Ɔ |
(?!.*a[@A]|.*[@A]a) | Forbid a with A/@ |
(?!.*m.rn|.*rn.*m) | Special case: forbid m next to homoglyph sequence rn |
.{11,} | After consuming the first letter, require ≥11 more characters → total length ≥12 |
$ | End of string |
Homoglyph Pairs Covered
| Homoglyph Pair | Rule |
|---|---|
| 0 / o / O | (?!.*0[oO]|.*[oO]0) |
| 1 / l / L / I | (?!.*1[lLI]|.*[lLI]1) |
| 5 / s / S | (?!.*5[sS]|.*[sS]5) |
| 2 / z / Z | (?!.*2[zZ]|.*[zZ]2) |
| 8 / b / B | (?!.*8[bB]|.*[bB]8) |
| 6 / g / G | (?!.*6[gG]|.*[gG]6) |
| 9 / g / G | (?!.*9[gG]|.*[gG]9) |
| c / C / Ɔ | (?!.*c[CƆ]|.*[CƆ]c) |
| a / A / @ | (?!.*a[@A]|.*[@A]a) |
| m / rn | (?!.*m.rn|.*rn.*m) |
Test Cases
| Input | Result | Reason |
|---|---|---|
john_doe | ✅ MATCH | Valid username |
abc123 | ✅ MATCH | Valid username |
a-b_c | ✅ MATCH | Valid username |
ab | ❌ NO MATCH | Too short (<3 chars) |
Aabc | ❌ NO MATCH | Must start with lowercase |
aPassword123456 | ✅ MATCH | Valid password |
aA1bcdefghijk | ✅ MATCH | Meets all password rules |
aAA1bbbbbbbb | ❌ NO MATCH | Consecutive repeated characters |
aPassword000 | ❌ NO MATCH | Contains 0 and o |
apP1mRnsecure | ❌ NO MATCH | Contains both m and rn |
Summary
Username Regex Enforces:
1. Starts with a lowercase letter
2. Contains only lowercase letters, digits, underscores, and dashes
3. Total length 3–16
4. No homoglyph or repetition checks (not needed)
Password Regex Enforces:
1. Starts with a lowercase letter
2. Contains uppercase, lowercase, and digits
3. 12+ characters long
4. No identical consecutive characters
5. Homoglyph/confusable pairs disallowed
6. m/rn visual‑collision disallowed
Leave a Reply
You must be logged in to post a comment.