Jump to content

[SOLVED] Regular Expression help


jayjay960

Recommended Posts

Hi, this is an unfinished script of mine for registering user accounts:

<?php
$username = $_GET['username'];
$password = $_GET['password'];
$confirmpassword = $_GET['confirmpassword'];
$email = $_GET['email'];
$birthday = $_GET['birthday'];
$birthmonth = $_GET['birthmonth'];
$birthyear = $_GET['birthyear'];
$pass = true;
$passmessage = '';
if (strlen($username)<3 || strlen($username)>20)
{
	$pass = false;
	$passmessage = 'Invalid username. Username must be between 3-20 characters long.';
}
if ($pass && preg_match('[^a-zA-Z0-9_]', $username))
{
	$pass = false;
	$passmessage = 'Invalid username. Username can only contain characters a-z, 0-9 or _.';
}
echo $passmessage;
?>

It's actually just a page called via ajax and the results are dumped in a box on the registration page.

 

At the moment I've just started to get it to validate the user details, but I've come across a problem in this particular if statement:

if ($pass && preg_match('[^a-zA-Z0-9_]', $username))

What I want to do is check if $username contains a character other than a-z, A-Z, 0-9 or _, but it's returning false every time. I've always had problems with regular expressions, and it's annoying me, because I've been using this reference and I can't see what I'm doing wrong. Can anyone help?

Link to comment
Share on other sites

A few things to keep in mind... when something like [^a-zA-Z0-9_] is successful (in that, in this case since we are dealing with a negated character class, if the value contained within $username doesn't have any characters outside of a-zA-Z0-9_), that preg statement will return 0:

 

example:

$username = 'thYui32_i9u';
echo preg_match('#[^a-zA-Z0-9_]#', $username); // output: 0

 

Since this is being checked in an if statement in conjunction with the variable $pass (which is defaulted to true -  and let's assume that the strlen is not an issue, in that the username passes this as well), this means that in a valid value for $username, the preg statement will return 0 (false), yet $pass =  true.. as a result, the entire if statement fails...

 

I think I would tackle it this way:

 

Example based off original code:

$username = 'thYui32_i9u.';
$pass = true;

if ($pass && preg_match('#^[a-z0-9_]+$#i', $username)){
    echo $username;
} else {
    $pass = false;
    echo $passmessage = 'Invalid username. Username can only contain characters a-z, 0-9 or _.';
}

 

@rhodesa, I'm not sure if that \\W is a mistype, but perhaps you meant simply \W? The thing to be careful of when dealing with shorthand character classes like \w or even \W is that depending on the locale, \w might not be only [a-zA-Z0-9_] (my locale allows a-zA-Z0-9_, exponents and accented characters as well) and as a result, this could botch up \W as well. If using those kinds of shorthands, I would first set the ctype setting to nullify these possible issues:

 

Insert this prior to any regex:

setlocale(LC_CTYPE, 'C');

Link to comment
Share on other sites

Thanks everyone. Actually I solved this late last night after a lot of looking around. I worked out I needed terminators like rhodesa said.

Also I seem to be getting the hang of regular expressions now, I worked out one for making sure email addresses follow the format abc@def.ghi.

 

If anyone's interested here's the username one:

<?php preg_match('/^[a-zA-Z0-9_]+$/', $username); ?>

 

The email one:

<?php preg_match('/^.+@.+\..+$/',$email); ?>

 

And another script I came up with to check if a date is valid (assuming the user has been given the options 1-31 for the date and 1-12 for the month. $birthday is the date, $birthmonth is the month and $birthyear is the year. at the end of the script $pass will be true if the date is valid or false if otherwise.)

 

<?php
$pass = false;
switch($birthmonth)
{
case '2':
{
	if (round($birthyear/4)==$birthyear/4)
	{
		if ($birthday>29)
		{
			$pass = false;
		}
	}
	else
	{
		if ($birthday>28)
		{
			$pass = false;
		}
	}
	break;
}
case '4':
{
	if ($birthday>30)
	{
		$pass = false;
	}
	break;
}
case '6':
{
	if ($birthday>30)
	{
		$pass = false;
	}
	break;
}
case '9':
{
	if ($birthday>30)
	{
		$pass = false;
	}
	break;
}
case '11':
{
	if ($birthday>30)
	{
		$pass = false;
	}
	break;
}
}
?>

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.