legobear154
legobear154

Reputation: 431

PHP preg_match_all pattern

I am using preg_match_all in php to check the characters in the username and password before i add them to the database, but I can't seem to get it to work the way I want. Here is what I have right now:

preg_match_all(USERNAME_PATTERN,$username,$usernameMatches);
preg_match_all(PASSWORD_PATTERN,$password,$passwordMatches);

Here are the patterns, defined as constants:

/*Username and Password Patterns*/
define("USERNAME_PATTERN","[-*_a-z0-9A-Z.]");
define("PASSWORD_PATTERN","[_a-z0-9A-Z]");

I don't know what is wrong with it. Its suppose to check to see if the username has anything other than a-z, A-Z, 0-9, the dash, the astrisk,the underscore, and a period. The password is the same as the username.

Here is the code I use to check:

if ($usernameMatches == 0){
echo("Bad characters in username<br />");
}

The password is the same.

Upvotes: 1

Views: 1255

Answers (4)

user1175332
user1175332

Reputation: 58

Before answering I would just say that by asking that question, I suspect that you are saving passwords directly as clear text. This is not a good solution because it exposes your users passwords. There is a discussion around that here with examples on how to do this in a more secure way.

As an added bonus the problem with invalid characters (in the password) will not be an issue for most cases, unless you are dealing with some legacy systems. The reason for this is that you will not store the actual password, but just the generated hash

Back to your question. One alternative I like is to check for the precense of any invalid characters. By adding ^ to the character list, you will match any character other than the list.

define("USERNAME_PATTERN","/[^*_a-z0-9A-Z.-]/");
if(preg_match(USERNAME_PATTERN, $username))
    echo 'Bad characters in username';

Upvotes: 1

Shiplu Mokaddim
Shiplu Mokaddim

Reputation: 57690

don't know what is wrong with it. Its suppose to check to see if the username has anything other than a-z, A-Z, 0-9, the dash, the astrisk,the underscore, and a period. The password is the same as the username.

You should check, if passed username/password is valid. You need this pattern. /^[\-\*\w\d\.]{6,12}$/, Here minimum and maximum length is 6 and 12 respectively.

define('PATTERN', '/^[\-\*\w\d\.]+$/');
if(preg_match(PATTERN, $username)){
// username is correct
} else {
// username is wrong.
}

Same for Password.

Upvotes: 1

Asaph
Asaph

Reputation: 162851

There are several issues with your code.

  1. Your regexes only match a single character.
  2. There are no begin and end anchors in your regex.
  3. Make sure you instantiate the matches array before calling preg_match_all()
  4. Your regex should be surrounded with a / (or other valid char).
  5. Check for a non-match by checking that the array is empty, not by checking if it's equal to zero. There are many type/value checking gotchas in php and it's best to avoid them.

Try this:

/*Username and Password Patterns*/
define("USERNAME_PATTERN","/^[-*_a-z0-9A-Z.]+$/");
define("PASSWORD_PATTERN","/^[_a-z0-9A-Z]+$/");

$usernameMatches = array();
$passwordMatches = array();

preg_match_all(USERNAME_PATTERN,$username,$usernameMatches);
preg_match_all(PASSWORD_PATTERN,$password,$passwordMatches);

if (empty($usernameMatches)){
    echo("Bad characters in username<br />");
}

if (empty($passwordMatches)){
    echo("Bad characters in password<br />");
}

BTW: Your code could simplified by simply using preg_match() instead of preg_match_all(). Something like this should work as well as your code:

/*Username and Password Patterns*/
define("USERNAME_PATTERN","/^[-*_a-z0-9A-Z.]+$/");
define("PASSWORD_PATTERN","/^[_a-z0-9A-Z]+$/");

if (!preg_match(USERNAME_PATTERN, $username)) {
    echo("Bad characters in username<br />");
}
if (!preg_match(PASSWORD_PATTERN, $password)) {
    echo("Bad characters in password<br />");
}

Upvotes: 3

robert
robert

Reputation: 3615

Use this:

define("USERNAME_PATTERN","/^[-*_a-z0-9A-Z.]+$/");
define("PASSWORD_PATTERN","/^[_a-z0-9A-Z]+$/");

Currently you allow for single-character usernames and passwords only. Also you have forgotten to encapsulate the regular expressions by / (or another character). (This is specific to PHP and some other languages, admittedly.) I have also added ^ and $ so that the whole input string is matched.

By the way, why bother with checking the passwords? Just require a certain minimum length, for example (but not at all checked for security):

define("PASSWORD_PATTERN","/^.{6,}$/");

Also, I don't get why you're using preg_match_all. A preg_match should do as well, and is probably easier to use:

if (!preg_match(USERNAME_PATTERN, $username) {
    echo("Bad characters in username<br />");
}

Upvotes: 2

Related Questions