tags:

views:

60

answers:

2
/^(?=.*\d)(?=.*[!@&.$#]).{7,16}$/

It should allow between 7 and 16 characters and contain at least 1 numeric character and 1 special character and can't start with a number. I tried testing it but it does not work?

+2  A: 

The first two conditions are fulfilled but the third (must not start with a digit) is not. Because .* in ^(?=.*\d) does match when there is a digit at the first position.

Try this instead:

/^(?=\D+\d)(?=.*[!@&.$#]).{7,16}$/

Here \D (anything except a digit) ensures that that is at least one non-digit character at the start.

Gumbo
I tried the above with test11. and it said it was invalid.
Xaisoft
@Xaisoft: `test11.` works for me. What language/regular expression implementation do you use?
Gumbo
I tested it in an online Regular Expression tester and it does work. I am using it in Teleriks RadInputManager's RegExpTextBoxSetting. It is c# and asp.net in the background.
Xaisoft
I got it, apparently, there is no reason to add the / at the beginning and end when specifying the expression with telerik. It would have be nice if they specified this though.
Xaisoft
+4  A: 

The only thing that I assume "does not work", which is a bit of a vague problem description to be honest, is the fact that it CAN start with a digit. Besides that, it works as you described.

Fix it like this:

/^(?=.*\d)(?=.*[!@&.$#])\D.{6,15}$/

A short explanation (in case you did not write the regex yourself):

^             # match the beginning of the input
(?=           # start positive look ahead
  .*          #   match any character except line breaks and repeat it zero or more times
  \d          #   match a digit: [0-9]
)             # end positive look ahead
(?=           # start positive look ahead
  .*          #   match any character except line breaks and repeat it zero or more times
  [!@&.$#]    #   match any character from the set {'!', '#', '$', '&', '.', '@'}
)             # end positive look ahead
\D            # match a non-digit: [^0-9]
.{6,15}       # match any character except line breaks and repeat it between 6 and 15 times
$             # match the end of the input
Bart Kiers
Thanks for the details. Is there reason why you put 6,16 instead of 7,16?
Xaisoft
I tried the above with the password test11. and it it said it was invalid.
Xaisoft
@Xaisoft, the string `test11.` (including the DOT) works just fine.
Bart Kiers
must be a telerik issue. I test yours fine in another program and it worked fine.
Xaisoft
@Xaisoft, `6,16` way a mistake: it should've been `6,15` (not `7,16`). The first character that'll be matched is a `\D` (non-digit) after which between 6 and 15 other characters should follow (`1+6,1+15` == `7,16`).
Bart Kiers
Thanks. I really appreciate the breakdown. How does it know not to allow a non-digit in the beginning. It seems to go in order, so I would think \D would be somewhere in the beginning similar to Gumbo's answer.
Xaisoft
Xaisoft, the `\D` *is* in the beginning. The positive lookaheads don't actually consume any characters from the input. The first one says the string needs to have a digit *somewhere*, and the second lookahead says there must be one of those other characters *somewhere*. Once those two conditions are met, *then* the actual matching begins. The first character must be a non-digit, and then there must be six to 15 additional characters. The lookaheads from earlier ensure that we don't need to worry about what those characters really are.
Rob Kennedy
Thanks Rob. You made Positive Lookaheads easier to understand. So the actually matching starts after the last postive lookahead if I understood you correctly.
Xaisoft
@Xaisoft, yes. Look arounds (ahead and behind) never match any character(s). The only "validate" from a certain position. For example, `.(?!a)` will match any **single** character that is not followed by an `a`.
Bart Kiers
Bart Kiers