views:

133

answers:

6
<?php
$username = "@#*(#(*#($&*#$";

if (preg_match("/^[0-9a-z-A-Z-_@ !]*/", $username)) 
{
   echo "true";
} else {
   echo "false";
}
?>
A: 

You probably meant to put your caret in the inside of the square brackets like so

if (preg_match("/[^0-9a-z-A-Z-_@ !]*/", $username)) 
MiffTheFox
+1  A: 

There is a problem here: Z-_, because there is a -, it means "characters from z to _. The correct regexp is /^[0-9a-zA-Z\-_@ !]*/, backslashing the -.

SHiNKiROU
It probably doesn't need the `z-A` either - I think that should really be `a-zA-Z`
a_m0d
That’s not a problem. The character class is correctly interpreted as `0-9`, `a-z`, `-`, `A-Z`, `-`, `_`, `@`, *space*, `!`.
Gumbo
+1  A: 

Two things:

  1. - within [...] is a special character indicating a range and needs to be escaped; and

  2. \w is a shortcut for [A-Za-z0-9_]. You should use it (although not using it isn't technically a problem here).

So:

if (preg_match('/^[\w\-@ !]*/', $username))
cletus
The `-` does not need to be escaped in any case. In this case you could also use `[\w-@ !]`.
Gumbo
+1  A: 

The problem is with the use of - in the regex. Also, you may want the regex to match the whole string, so you should also place an end of string marker.

if(preg_match('/^[0-9a-zA-Z\-_@ !]*$/', $username)
z33m
+2  A: 

As written, that regex will match zero or more of the listed characters at the beginning of the string--which means it will always succeed, no matter what's in the input string. If you want to restrict the input to just those characters, you need to anchor it at both ends:

'/^[0-9a-zA-Z_@ !-]*$/'

But be aware that it will still match an empty string; if you want to prevent that, you should should change the * to a +.

Notice how I removed two of the hyphens and added one to the end of the character class. Because hyphens have special meaning in character classes, you should make it as clear as possible when you want to match one literally. You do that either by escaping it with a backslash, or by placing it in the first or last position.

The "extra" hyphens in your regex were in fact treated as literal hyphens because they couldn't form ranges where they were--in each case the preceding character was already part of a range. It's not a good idea to rely on that behavior, though; not all regex flavors are as forgiving as PHP. And of course, it looks like an error to anyone reading your code.

Alan Moore
A: 

You need to specify the end of the string. Otherwise even a zero times repetition of the character class (results in a regular expression that is equivalent to ^) would matches any string:

/^[0-9a-z-A-Z-_@ !]*$/
Gumbo