0

I need my regex statement to do the following: takes:

  • a-z 0-many times,
  • 0-9 0-3 times,
  • & 0-many times,
  • " " 0-1 time,
  • be a minimum of 8 characters.

I also use this website to test my code - https://regexr.com.

My regex:

([a-zA-Z&]*[0-9]{0,3}[\s]?)\w{8,}

These should work:

abcD &EFG,
ABCde f123,
&&12ADSD&&.

these should not:

a bcD &EFG,
AB5Cde f123,
&&12ADSD&&34,
1234567,
nope.

Problem is that my regex will accept any number of digits regardless of me putting my limit on it and it will accept spaces in the middle of words but unpredictably and i don't know why.

I'm new to regex so be gentle with me

Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
Hoop
  • 3
  • 2

2 Answers2

1

The start of your current pattern ([a-zA-Z&]*[0-9]{0,3}[\s]?)\w{8,} has quantifiers 0+ times, 0-3 times or optional.

At the end it should match at least 8+ times a word character which will not match any of the examples.

You could use a negative lookahead (?! to assert that there are no 4 digits occurring or 2 times a space and then repeat matching 8+ times what is listed in the character class.

^(?!(?:[^\r\n0-9]*[0-9]){4})(?!(?:\S* ){2})[a-zA-Z0-9 &]{8,}$
  • ^ Start of string
  • (?! Negative lookahead, assert what is on the right is not
    • (?:[^\r\n0-9]*[0-9]){4} Match 4 times a digit
  • ) Close lookahead
  • (?! Negative lookahead, assert what is on the right is not
    • (?: Non capturing group
      • \S* Match 0+ times a non whitespace char, then match a space
    • ){2} Close non capturing group and repeat 2 times
  • ) Negative lookahead, assert not 2 spaces
  • [a-zA-Z0-9 &]{8,} Match 8+ times any of the listed
  • $ End of string

Regex demo

The fourth bird
  • 154,723
  • 16
  • 55
  • 70
  • Thats awesome, i never really thought about using a negative look-ahead because i never knew the application of it. I am curious to know why i cant just use '\s' instead of \r\n when its supposed to include it. putting it in the second capture group changes nothing however. – Hoop Oct 01 '19 at 17:20
  • @Hoop But I get your point, I have updated the negated character class to `\S*` to match 0+ times a non whitespace char. – The fourth bird Oct 01 '19 at 17:38
0

somewhat different with positive lookahead

Pattern.compile("(?=^[^ ]* ?[^ ]*$)(?=^([^0-9]*[0-9]?){1,3}$)^[A-Za-z0-9\\& ]{8,}$")

[a-zA-Z0-9\\& ]{8,} : 8 or more character of the permitted ones.

(?=^[^ ]* ?[^ ]*$) : positive lookahead: permit a single space

(?=^([^0-9]*[0-9]?){1,3}[^0-9]*$) : positive lookahead permitting at most three instances of digits

https://regex101.com/r/FvaslE/2

Lutz
  • 612
  • 3
  • 8
  • Hey man, thanks for your help, both of these comments have helped my understanding of lookarounds. thank you for taking the time :) – Hoop Oct 01 '19 at 17:23