A solid nickname regexp
I want a regular expression to validate a nickname: 6 to 36 characters, it should contain at least one letter. Other allowed characters: 0-9 and underscores.
This is what I have now:
if(!preg_match('/^.*(?=\d{0,})(?=[a-zA-Z]{1,})(?=[a-zA-Z0-9_]{6,36}).*$/i', $value)){
echo '开发者_JAVA百科bad';
}
else{
echo 'good';
}
This seems to work, but when a validate this strings for example:
11111111111a > is not valid, but it should aaaaaaa!aaaa > is valid, but it shouldn't
Any ideas to make this regexp better?
I would actually split your task into two regex:
- to find out whether it's a valid word:
/^\w{6,36}$/i
- to find out whether it contains a letter
/[a-z]/i
I think it's much simpler this way.
Try this:
'/^(?=.*[a-z])\w{6,36}$/i'
Here are some of the problems with your original regex:
/^.*(?=\d{0,})(?=[a-zA-Z]{1,})(?=[a-zA-Z0-9_]{6,36}).*$/i
(?=\d{0,})
: What is this for??? This is always true and doesn't do anything!(?=[a-zA-Z]{1,})
: You don't need the{1,}
part, you just need to find one letter, andi
flag also allows you to omitA-Z
/^.*
: You're matching these outside of the lookaround; it should be inside(?=[a-zA-Z0-9_]{6,36}).*$
: this means that as long as there are between 6-36\w
characters, everything else in the rest of the string matches! The string can be 100 characters long mostly containing illegal characters and it will still match!
You can do it easily using two calls to preg_match as:
if( preg_match('/^[a-z0-9_]{6,36}$/i',$input) && preg_match('/[a-z]/i',$input)) {
// good
} else {
// bad
}
精彩评论