2

I need to come up with a regular expression that validates a string with the following requirements:

  1. Only contains alphanumeric and the following special characters: !@#$%^&*
  2. Contains at least 1 of the special characters in the list above
  3. The required special character can appear anywhere in the string (for example: !abc, a!bc, abc!)

I keep getting close, but fail on one of the conditions.

Thanks!

10
  • You should better set a lower bound (minimum length) instead of an upper bound (allowed characters). Commented Jun 13, 2011 at 20:46
  • @Tomalak the only reason I can think of is it might minimize the "forgot my password" instances, but that's specious at best Commented Jun 13, 2011 at 20:46
  • @Tomalak - because injection attacks happen when users are allowed to enter anything they want. If you could enter a semicolon or quotes, an attacker could enter '; DROP DATABASE master;, which could take down your whole database instance. Commented Jun 13, 2011 at 20:48
  • 3
    @Keith: This is a laughable reason and you know it. SQL injection is a solved problem. Also: You are not inserting clear text passwords into a database, period. Commented Jun 13, 2011 at 20:50
  • @KeithS, which would not be a problem if the programmer only used parameterized SQL queries, which EVERYONE should! Commented Jun 13, 2011 at 20:58

4 Answers 4

2

The regular expression you're looking for is:

/^(?=.*[!@#$%^&*])[A-Za-z0-9!@#$%^&*]+$/

which will guarantee the string contains one of your special characters using (?=) positive lookahead.

--EDIT--

It appears Bohemian decided to completely ignore the comment section of my answer and edited the above example to remove its "unnecessary" character escaping. I really wish he hadn't because I believe my justification is correct, but there you have it. My original example was:

/^(?=.*[\!\@\#\$\%\^\&\*])[A-Za-z0-9\!\@\#\$\%\^\&\*]+$/
Sign up to request clarification or add additional context in comments.

12 Comments

And yes, while it's not necessary to quote many, if not all, of the special chars appearing within the character class, it's always a good idea to do so since it clearly indicates the programmer's intent.
@Rob Raisch - unnecessarily escaping will lead longer and confusing regex in many languages since you will have to escape the ``
@Rob Raisch - you are right, mine will allow more chars. To fix that I basically came to your answer, so deleting mine. Still, you should probably not have all the escapes.
Best practice dictates clear communication of programmer intent and since regexes can be confusing, it's always best to err on the side of verbosity if required to underscore that intent. Anyone knowledgeable in regular expressions can tell what I intended. For example, which tells you more [*.$] or [*\.\$]? No matter the dialect, the intent that these are literal characters is clear.
@AlanMoore, thanks for your comment. (Love your work. When's Watchmen II coming out? ;)
|
1
^(?=.*?[!@#$%\^&*])((?!_)[\w!@#$%\^&*])+$

It looks ensure the special character is found anywhere in the string. Once it finds it, it matches the rest of the string as long as the string consists of only word characters, digits, and the special characters.

Edit: The negativelookahead prevents _ (underscore).

5 Comments

\w will match '_' which is not in the OP's list of required characters.
@ColonelPanic, I'm curious why you chose this answer over mine since it allows a character that was not in your specification?
you are correct, i didn't catch that. thanks Rob, and thanks agent-j. sorry about that.
By removing the 1 character you don't like (the underscore), you can have all the non-english letter characters your users could ever want to use. That's why the gods gave us character classes, so we all wouldn't have to remember the other letters. ;-)
About the "non-English" letters (and I think "non-ASCII" is a better way to describe them), it depends on which regex flavor you're using. There are still many flavors in which \w is equivalent to [A-Za-z0-9_]. But Unicode or ASCII, the \d in [\w\d] is always redundant.
0

Say you want minimum requirements of "at least one non-alphanumeric character, at least 8 characters". Use two look-aheads:

^(?=.*[^a-zA-Z0-9])(?=.{8,}$)

Other than that - let users choose the passwords they like.

Comments

0

This one seems to be working:

^.*(?=.*[a-zA-Z])(?=.*[!@#$%^&*]).*$

If you would like to set an minimum length as well, use this (using 10 characters minimum):

^.*(?=.{10,})(?=.*[a-zA-Z])(?=.*[!@#$%^&*]).*$

See rubular

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.