1

I've been trying to learn lookaheads in Regex.

I am trying to match an expression that starts with a lowercase letter and has 4 or more digits.

/(?=\A[a-z])(?=\D\d{4,})/

This works if the digits are all adjacent to eachother, but not if they're away from each other. For example

z1562 - Passes (all 4 digits are adjacent)

z15a62 - Fails - Has 4 digits

Where am I going wrong here? How can I fix this?

Richard Hamilton
  • 22,314
  • 9
  • 45
  • 77
  • A lookahead accepts the same kinds of patterns that you write without lookaheads. If your pattern inside the lookahead doesn't make sense by itself, then it won't make sense within a lookahead either. You need to work out why your pattern within the lookahead doesn't match `15a62`. – Kenneth K. Dec 07 '15 at 23:19

1 Answers1

4

You can use

\A(?=[a-z])(?=(?:\D*\d){4,})
              ^^^^^^^^^

You need to use * to match any number of non-digits before a digit, at least 4 times (thus, you need to group the \D*\d and apply the limiting quantifier to the group).

See the regex demo

It is also worth mentioning that \A anchor should be moved outside the lookahead so that it was only triggered once at the beginning of the string. It will also make the second lookahead to only trigger once, right after the first one.

Wiktor Stribiżew
  • 484,719
  • 26
  • 302
  • 397
  • FYI: You may even use `{4}` instead of `{4,}` since 4 is enough for the lookahead to return true. – Wiktor Stribiżew Dec 07 '15 at 23:02
  • I've only seen `?=` for positive lookahead and `?!` for negative lookahead. What does `?:` refer to? – Richard Hamilton Dec 07 '15 at 23:04
  • The `(?:...)` is a [non-capturing group](http://stackoverflow.com/questions/3512471/what-is-a-non-capturing-group), it is only used for grouping, not capturing submatches. Just is a bit more efficient and does not mess the output structure. – Wiktor Stribiżew Dec 07 '15 at 23:05