1

I need to use PHP to validate usernames, and I only want them to use alphanumeric, as well as dash (-), underscore (_) and period (.)

Is this right?

preg_match("/[A-Za-z0-9_-.]/",$text);
1
  • 1
    Hi Brendan - the easiest way to find out if it's right is to actually test it. Commented Oct 30, 2009 at 9:33

2 Answers 2

4

No it isn't (although, I suppose you already suspected that, since otherwise you wouldn't be asking). :)

When defining a character group, the dash is used to define a range, just as you do A-Z means all characters between A and Z. However, you also do _-., meaning all characters between _ and . (I don't know which that is, but you can look it up in an ASCII-table). To allow matching of a dash in a character group, it has be placed anywhere where it can't be interpreted as a character range, which is usually first or last (but see the comments for other creative ways ;) ).

preg_match("/^[A-Za-z0-9_.-]+$/",$text);

As pointed out in the comments, you'll need to anchor it too, to make sure there are no charachters outside the matched range (that's what the ^, which matches beginning of string, and $, which matches end of string, are for). You'll also need to make sure that you can match more than one character. So add a + in there (or * if you want to allow empty strings), meaning one or more characters.

HTH

Sign up to request clarification or add additional context in comments.

7 Comments

The dash could also be escaped: /[A-Za-z0-9_\-.]/, or placed at the start: /[-A-Za-z0-9_.]/ or even in between ranges: /[A-Z-a-z0-9_.]/ to match the literal -.
that regex can be written simply as /[\w.-]/
@roe, But not entirely correct: I said 'in between ranges', but right after a range is sufficient: [A-Za-z0-9-_.] would do the trick.
It also needs to be anchored, right now that'd match $text as long as it had one valid character and there rest were invalid.
@newacct: not quite - \w will also match accented and other special characters (Äáß etc.).
|
0

You need to anchor the pattern at beginning an end, right now it'd match $text as long as there was just one valid character and the rest were invalid. Use this:

if (preg_match('/^[\w.-]+$/', $text)) { /* valid */ }

\w is the same thing as [0-9A-Za-z_]. Another way to do it would be to inverse the pattern and search for any invalid characters and check none are matched:

if (!preg_match('/[^\w.-]/', $text)) { /* valid */ }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.