php - My regular expression does not check the names correctly ← (PHP)

I created this function to check Spanish names and it is not working.

This is the string that I am passing to the function:

"ГЃngel Manuel"

Here you have the function:

/**
* checks First Name or Last Name
*
* @access public
* @param bool $valid
* @param string $name
* @return bool
*/
    
public static function checkName($valid, $name) {
    if(!preg_match('/^(?=.{3,18})[A-ZÁÉÍÓÚ][a-zñáéíóú]+(?:\s[A-ZÁÉÍÓÚ][a-zñáéíóú]+)?/', $name)) {
        $valid=false;
    }
    return $valid;
}

Thanks a lot!

Answer



Solution:

You need to

  • add $ at the end of the lookahead to actually restrict max length of the matched string, (?=.{3,18}$) and at the end of the regex pattern (or (?=\X{3,18}$) to allow 3 to 18 any graphemes)
  • add u flag since your input is a Unicode string
  • use \p{Lu} to match any Unicode uppercase letters, and \p{Ll} to match any Unicode lowercase letters
  • and just return true or false depending on the result of preg_match, no need to pass $valid as function argument.

You can use

public static function checkName($name) {
    if(!preg_match('/^(?=.{3,18}$)\p{Lu}\p{Ll}+(?:\s\p{Lu}\p{Ll}+)?$/u', $name)) {
        return false;
    }
    return true;
}

Details

  • ^ - start of string
  • (?=.{3,18}$) - string must have 3 to 18 chars ((?=\X{3,18}$) to allow 3 to 18 any graphemes)
  • \p{Lu}\p{Ll}+ - one Unicode uppercase letter followed with one or more lowercase letters
  • (?:\s\p{Lu}\p{Ll}+)? - an optional sequence of a whitespace and then one Unicode uppercase letter followed with one or more lowercase letters
  • $ - end of string.

Source