Honestly the best way to deal with this in PHP is not to use a Regular Expression. PHP has a series of "ctype" methods (docs here) built in to the language to allow you to determine character types, and these methods are much easier to use for something like this than Regex. Don't get me wrong Regex is a great and powerful tool, but it's way too much complexity for this problem. Even if you need to extend my solution below with regex for complex pattern matching later on, you can just add it / them for the specific needs you have and you will not have to use it to determine character types.
I would seriously recommend that you write a series of very small functions / methods that you can then compose together to check that the string you are validating passes all of the criteria, like this (you can paste the example into a file and run it on the command-line to see the output from the script below the class definition):
<?php
/* Example written assuming that these methods are all
* part of a Class, hence the access declarations etc.
* If you want to write them as a function library that
* would work fine too
*/
class InputValidation {
const MIN_LENGTH = 6;
const MAX_LENGTH = 40;
public function isLongerThanMinLength($text) {
$len = strlen($text);
if ($len > self::MIN_LENGTH) {
return TRUE;
} else {
return FALSE;
}
}
public function isShorterThanMaxLength($text) {
$len = strlen($text);
if ($len <= self::MAX_LENGTH) {
return TRUE;
} else {
return FALSE;
}
}
public function hasAlphaAndDigitChars($text) {
if (ctype_alpha($text) || ctype_digit($text)) {
return FALSE;
} else {
if (ctype_alnum($text)) {
return TRUE;
} else {
return FALSE;
}
}
}
public function validInput($text) {
if (!$this->isLongerThanMinLength($text)) {
return FALSE;
}
if (!$this->isShorterThanMaxLength($text)) {
return FALSE;
}
if (!$this->hasAlphaAndDigitChars($text)) {
return FALSE;
}
return TRUE;
}
}
$inst = new InputValidation;
$test1 = "Hello"; // too short
$test2 = "pneumonoultramicroscopicsilicovolcanoconiosis"; // too long
$test3 = "pneumonoultramicroscopicsil1covolcanocon"; // right length and includes at least one number
$test4 = "123456789123456789"; // right length, but no alphabet chars
$test5 = "HelloMyName"; // right length, but no numeric chars
$test6 = "Hello My Name"; // right length, but has whitespace
$test7 = "Hello^My%Name1"; // right length, but has 'special' chars
print "\n";
var_dump($inst->validInput($test1));
print "\n";
var_dump($inst->validInput($test2));
print "\n";
var_dump($inst->validInput($test3));
print "\n";
var_dump($inst->validInput($test4));
print "\n";
var_dump($inst->validInput($test5));
print "\n";
var_dump($inst->validInput($test6));
print "\n";
var_dump($inst->validInput($test7));
print "\n";
print "\n";
exit();
?>
This way you can use different validation methods to increase the complexity of this validation or create new validations by putting together the existing rules in a different way, or easily add new rules by adding new short methods.