I’m trying to understand what’s wrong with this regex pattern:
'/^[a-z0-9-_.]*[a-z0-9]+[a-z0-9-_.]*{4,20}$/i'
What I’m trying to do is to validate the username. Allowed chars are alphanumeric, dash, underscore, and dot. The restriction I’m trying to implement is to have at least one alphanumeric character so the user will not be allowed to have a nickname like this one: _-_.
The function I’m using right now is:
function validate($pattern, $string){ return (bool) preg_match($pattern, $string); }
Thanks.
EDIT
As @mario said, yes,t here is a problem with *{4,20}
.
What I tried to do now is to add ( )
but this isn’t working as excepted:
'/^([a-z0-9-_.]*[a-z0-9]+[a-z0-9-_.]*){4,20}$/i'
Now it matches ‘aa–aa’ but it doesn’t match ‘aa–‘ and ‘–aa’. Any other suggestions?
EDIT
Maybe someone wants to deny not nice looking usernames like “_..-a”. This regex will deny to have consecutive non alphanumeric chars:
/^(?=.{4,20}$)[a-z0-9]{0,1}([a-z0-9._-][a-z0-9]+)*[a-z0-9.-_]{0,1}$/i
In this case _-this-is-me-_
will not match, but _this-is-me_
will match.
Have a nice day and thanks to all 🙂
Advertisement
Answer
Don’t try to cram it all into one regex. Make your life simpler and use a two step-approach:
return (bool) preg_match('/^[a-z0-9_.-]{4,20}$/', $s) && preg_match('/w/', $s);
The mistake in your regex probably was the mixup of *
and {n,m}
. You can have only one of those quantifiers, not *{4,20}
both after another.
Very well, here is the cumbersome solution to what you want:
preg_match('/^(?=.{4})(?!.{21})[w.-]*[a-z][w-.]*$/i', $s)
The assertions assert the length, and the second part ensures that at least one letter is present.