2

I'm currently looking for a regex that verify's the following requirements:

  • Should contain atleast 8 digits (0-9).
  • Between the digits it is allowed to use other characters (a-z) (also upper case).
  • It should contain max 20 characters (a-z 0-9).

example:

12345678: true
123adafa45678: true
123ab456: false (needs atleast 8 digits, now only 6)
ab12345a678: true 
ab123456789afgb2459a2: false (more then 20 characters)

I tried serveral things but if I use something like: (\D*\d\D*){8,} then it works but it doesn't meet the last requirement (up to 20 characters).

JeroenE
  • 603
  • 7
  • 22

1 Answers1

2

Use a lookahead for 8 digits:

^(?=(.*\d){8})[a-zA-Z\d]{8,20}$

See live demo.

Bohemian
  • 412,405
  • 93
  • 575
  • 722
  • This is a nice one, thank you! Works like a charm! Have to make two more so hopefully I'll understand it later today. :) – JeroenE Dec 28 '16 at 14:03
  • Yes, just it is advisable to replace `(.*\d){8}` with `(?:\D*\d){8}`. – Wiktor Stribiżew Dec 28 '16 at 14:04
  • Thanks Wiktor! Changed that. – JeroenE Dec 28 '16 at 14:05
  • @WiktorStribiżew your suggestion fails if there are multiple targets separated by newlines, because `\D` matches newlines but dot does not. See your version incorrectly matching [here](http://rubular.com/r/7bmdOzWgH9). – Bohemian Dec 28 '16 at 17:01
  • @Bohemian: The string that is passed to this regex cannot be a multiline string. It is a *password* validation. It does not matter whether you use `\D` or `.`. I suggested `(?:[a-z]*\d){8}` in my comment anyway. – Wiktor Stribiżew Dec 28 '16 at 17:25
  • @wiktor then the millionth of a second you'll save in "performance" using `\D` on such a tiny input isn't worth bothering about – Bohemian Dec 28 '16 at 17:29