Your regex would be /^(?![a-zA-Z0-9]{2}_)/
. It means "start with not {two alphanumeric characters and an underscore}".
Mewp
2010-08-18 17:13:00
Your regex would be /^(?![a-zA-Z0-9]{2}_)/
. It means "start with not {two alphanumeric characters and an underscore}".
A simple way in this case is just to break it into cases: the username either starts with a non-alpha, or an alpha and a non-alpha, or two alphas and non-underscore, so roughly like:
/^([^A-Za-z]|[A-Za-z][^A-Za-z]|[A-Za-z][A-Za-z][^_])/
Just put in a negative assertion, like this:
/^([^A-Za-z0-9]{2}(?!\_)|[A-Za-z0-9]{3,27})/
^^--Notice the assertion.
Here is a full test case:
<?php
$names = array('SU_Coolguy','MR_Nobody','my_Pony','__SU_Coolguy','MRS_Nobody','YourPony');
foreach($names as $name){
echo "$name => ";
if(preg_match('/^([^A-Za-z0-9]{2}(?!\_)|[A-Za-z0-9]{3,27})/',$name)) {
echo 'ok';
}else{
echo 'fail';
}
echo "\n";
}
?>
which outputs this:
SU_Coolguy => fail
MR_Nobody => fail
my_Pony => fail
__SU_Coolguy => ok
MRS_Nobody => ok
YourPony => ok
This uses a negative lookahead:
^(?![A-Za-z]{2}_)[A-Za-z0-9_]{3,27}$
Lets break it down:
Assert position at the beginning of a line (at beginning of the string or after a line break character) «^»
Assert that it is impossible to match the regex below starting at this position (negative lookahead) «(?![A-Za-z]{2}_)»
Match a single character present in the list below «[A-Za-z]{2}»
Exactly 2 times «{2}»
A character in the range between “A” and “Z” «A-Z»
A character in the range between “a” and “z” «a-z»
Match the character “_” literally «_»
Match a single character present in the list below «[A-Za-z0-9_]{3,27}»
Between 3 and 27 times, as many times as possible, giving back as needed (greedy) «{3,27}»
A character in the range between “A” and “Z” «A-Z»
A character in the range between “a” and “z” «a-z»
A character in the range between “0” and “9” «0-9»
The character “_” «_»
Assert position at the end of a line (at the end of the string or before a line break character) «$»