Here is a safer version of Gonzalo's filter, which only removes the validation error that reads "Usernames can only contain lowercase letters (a-z) and numbers.". It instead uses a similar validation but allows the same characters seen in sanitize_email().
The only caveat is this checks the error message name. If WordPress changes that error message in the future, this will stop working. But it's the only way to target that specific validation message.
/**
* Allow users to sign up using an email address as their username.
* Removes the default restriction of [a-z0-9] and replaces it with [a-z0-9+_.@-].
*
* @param $result
*
* @return array $result
*/
function wpse_295037_disable_username_character_type_restriction( $result ) {
$errors = $result['errors'];
$user_name = $result['user_name'];
// The error message to look for. This should exactly match the error message from ms-functions.php -> wpmu_validate_user_signup().
$error_message = __( 'Usernames can only contain lowercase letters (a-z) and numbers.' );
// Look through the errors for the above message.
if ( !empty($errors->errors['user_name']) ) foreach( $errors->errors['user_name'] as $i => $message ) {
// Check if it's the right error message.
if ( $message === $error_message ) {
// Remove the error message.
unset($errors->errors['user_name'][$i]);
// Validate using different allowed characters based on sanitize_email().
$pattern = "/[^a-z0-9+_.@-]/i";
if ( preg_match( $pattern, $user_name ) ) {
$errors->add( 'user_name', __( 'Username is invalid. Usernames can only contain: lowercase letters, numbers, and these symbols: <code>+ _ . @ -</code>.' ) );
}
// If there are no errors remaining, remove the error code
if ( empty($errors->errors['user_name']) ) {
unset($errors->errors['user_name']);
}
}
}
return $result;
}
add_filter( 'wpmu_validate_user_signup', 'wpse_295037_disable_username_character_type_restriction', 20 );