views:

909

answers:

2

I am building a user registration form using C# with .NET. I have a requirement to validate user entered password fields. Validation requirement is as below.

  1. It should be alphanumeric (a-z , A-Z , 0-9)
  2. It should accept 6-10 characters (minimum 6 characters, maximum 10 characters)
  3. With at least 1 alphabet and number (example: stack1over)

I am using a regular expression as below.

^([a-zA-Z0-9]{6,10})$

It satisfies my first 2 conditions. It fails when I enter only characters or numbers.

+6  A: 

Use positive lookahead

^(?=.*[a-zA-Z])(?=.*[0-9])[a-zA-Z0-9]{6,10}$

Look arounds are also called zero-width assertions. They are zero-width just like the start and end of line (^, $). The difference is that lookarounds will actually match characters, but then give up the match and only return the result: match or no match. That is why they are called "assertions". They do not consume characters in the string, but only assert whether a match is possible or not.

The syntax for look around:

  • (?=REGEX) Positive lookahead
  • (?!REGEX) Negative lookahead
  • (?<=REGEX) Positive lookbehind
  • (?<!REGEX) Negative lookbehind
Amarghosh
Thanks for your reply.But its not working.Try changing the order you inserted the values.It wont work properly
Madhu
tried here with no problems;
Rubens Farias
Wow, I didn't hit upon this. Imo, it works as expected, at least in Python)
Rorick
try some text starting with numbers. If you use alphabets in the beginning of the word, it works as you expected. But when you start the same with numbers, it doesnt.(I am using .net with c#)Thanks for your patience.
Madhu
@Madhu I tested it with expresso and it is working fine for strings starting with numbers. (don't have .net development environment with me). Post an example that fails with it and we might be able to tell you whats the issue.
Amarghosh
+3  A: 

Pass it through multiple regexes if you can. It'll be a lot cleaner than those look-ahead monstrosities :-)

^[a-zA-Z0-9]{6,10}$
[a-zA-Z]
[0-9]

Though some might consider it clever, it's not necessary to do everything with a single regex (or even with any regex, sometimes - just witness the people who want a regex to detect numbers between 75 and 4093).

Would you rather see some nice clean code like:

if not checkRegex(str,"^[0-9]+$")
    return false
val = string_to_int(str);
return (val >= 75) and (val <= 4093)

or something like:

return checkRegex(str,"^7[5-9]$|^[89][0-9]$|^[1-9][0-9][0-9]$|^[1-3][0-9][0-9][0-9]$|^40[0-8][0-9]$|^409[0-3]$")

I know which one I'd prefer to maintain :-)

paxdiablo
Do you mean all these in a single expression as belowvalidationexpression="^([a-zA-Z0-9]{6,10})$[a-zA-Z][0-9]"
Madhu
No. I mean something like: if (!str.match(re1)) return false; if (!str.match(re2)) return false; return str.match(re3); - that's three separate invocations with three separate regexes.
paxdiablo