Вы можете попробовать это ...
if (!preg_match('/(?=^.{8,40}$)((?=.*\d)|(?=.*\W+))(?![.\n])(?=.*[A-Z])(?=.*[a-z]).*$/', html_entity_decode($this->request->post['password'], ENT_QUOTES, 'UTF-8'))) {
Это в течение 8 мин. и 40 макс. символы, одна заглавная и одна строчная буква. Если вы хотите sh проверить специальный символ, вы должны добавить дополнительное регулярное выражение.