Here:
^[a-z0-9]+(?:[._-]?[a-z0-9]+)*$
Demo
Explanation:
- The first
[a-z0-9]+
ensures the user name STARTS with a (lower case) letter or number.
-
[._-]?
allows the presence of one (or none) "."
, "_"
or "-"
character.
- The final
[a-z0-9]+
ensures the user name ENDS with a (lower case) letter or number.
- Wrapping this second group in
(...)*
allows for multiple "."
, "_"
or "-"
characters in the middle of the user name (so long as they are separated by letters/numbers), e.g. "ab.bc-ad"
.
Edit:
I just noticed your final condition for matching:
And it must min. have 3 characters.
The easiest way to add this as part of the regex is with a lookahead - i.e.:
^(?=.{3,})[a-z0-9]+(?:[._-]?[a-z0-9]+)*$
Here is an updated demo with additional test strings.
Edit2:
The above is perfectly valid for PHP
. However, in case anyone reading this is actually looking for an answer using grep
(i.e. nothing to do with PHP
...)
First note that you can use the -x
modifier to match an exact string, and therefore do away with the ^
and $
anchors. You then have two options to make this work:
-
Use the above code with grep -P
, or equivalently pcregrep
, since the standard grep
tool does not support lookaheads:
pcregrep -x "(?=.{3,})[a-z0-9]+([._-]?[a-z0-9]+)*" <filename>
-
Use grep -E
, or equivalently egrep
, for the special character support; pipe the output through a second grep
to satisfy the "min 3 chars" condition:
egrep -x "[a-z0-9]+([._-]?[a-z0-9]+)*" <filename> | grep ...