Skip to content
Advertisement

Regex to validate username

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.

User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement