John Batdorf
John Batdorf

Reputation: 2542

.NET Regex Not working as it should

I have the following regex pattern: (.NET 1.1 Regex Validator)

^(?=.*[A-Za-z])[a-zA-Z0-9@\\-_\\+\\.]{6,32}$

I need to meet the following requirements:

6 to 32 characters must contain at least one letter. Allowed characters are letters (a-z, A-Z), numbers (0-9), @ ("at" symbol), . (period), _ (underscore), + (plus), - (minus).

Any entries starting with numeric values, seem to be 'skipped' until non numeric values are encountered.

123abc fails
123abcde fails
123abcdef passes

So I see that it's 'counting' the look ahead AFTER the numeric values, why?

Thanks.

Upvotes: 1

Views: 1055

Answers (3)

Alan Moore
Alan Moore

Reputation: 75222

Have you tried refactoring the regex? For example:

^(?=[a-zA-Z0-9_@+.-]{6,32}$).*[A-Za-z].*$

Or just "pad" your lookahead so it has to match all the way to the end:

^(?=.*[A-Za-z].*$)[a-zA-Z0-9_@+.-]{6,32}$

Maybe that will reset the match position so the second part can start matching at the beginning. It shouldn't be necessary, of course, but I can't see any reason why your regex wouldn't work as written.

Upvotes: 1

Richard Szalay
Richard Szalay

Reputation: 84744

It's quite possible that it's a bug in .NET 1.1. All of your "fail" examples work using Regex Hero, which is based on Silverlight which uses the .NET 2.0 Regex implementation.

You might try using a positive look-behind assertion instead and see if that gets around the problem:

^[a-zA-Z0-9@\-_\+\.]{6,32}(?<=.*[A-Za-z])$

Edit: Considering this is an ASP.NET validator, you should double check that it's not failing client validation (javascript). Some advanced features (like zero-width look ahead/behinds) are not supported by some browsers.

Try to disable client side validation by setting EnableClientScript to false on the RegularExpressionValidator and see if that fixes the problem. If it does, then it's a browser support issue and I'd recommend splitting your validation into two:

  1. ^[a-zA-Z0-9@\-_\+\.]{6,32}$ # must be 6-32 characters
  2. ^.*[A-Za-z].*$ # must contain a letter

Upvotes: 2

Greg Bacon
Greg Bacon

Reputation: 139471

It's counting the lookahead after the digits because you allowed as much with

(?=.*[A-Za-z])

The .* means "after zero or more characters."

If you want to force a letter at the beginning, modify your pattern:

^[A-Za-z][-a-zA-Z0-9@_+.]{5,31}$

Upvotes: 0

Related Questions