-10

I want to match/extract the last 4 consecutive digits in a string. The pattern I need to match is therefore [0-9]{4}, but only the last instance of it in the string - if there are any non-numbers in between, it should match the next instance instead.

Some examples:

ABC123456789A9876  // should extract 9876
ABCD1234567890F23  // should extract 7890
1234ABCD567JIJLMN  // should extract 1234
ABCDEFG1234-!.567  // should extract 1234

How can I accomplish this using regex? Alternatively if there's an easier way to do this programmatically with PHP/Laravel I'd also be open to it.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Hashim Aziz
  • 4,074
  • 5
  • 38
  • 68
  • 5
    What have you tried to achieve this? – matiaslauriti Aug 12 '23 at 21:36
  • @matiaslauriti A lot in the last few hours, but since nothing came close to working I don't see the reason in polluting the question with irrelevant attempts. See also: [every](https://stackoverflow.com/questions/10294626/regex-to-check-for-4-consecutive-digits) other [question](https://stackoverflow.com/questions/41870124/regex-to-find-last-occurrence-of-pattern-in-a-string) about [regex](https://stackoverflow.com/questions/40926332/how-to-match-the-last-occurrence-of-a-pattern-using-regex). – Hashim Aziz Aug 12 '23 at 22:08
  • 3
    [This question is being discussed on meta.](https://meta.stackoverflow.com/questions/426031/why-was-my-regex-question-downvoted-and-closed-when-its-as-good-or-better-than) – MisterMiyagi Aug 15 '23 at 15:54

1 Answers1

2

Here are two ways to do that.

Use \K

Match

.*\K\d{4}

Demo

The component parts of the expression are as follows.

.*     # match zero or more characters other than line
       # terminators, as many as possible
\K     # reset the start of the match and discard all
       # previously-consumed characters
\d{4}  # match 4 digits

Use a capture group

Match

.*(\d{4})

and extract the four digits from capture group 1.

Demo

The expression reads, "Match zero or more characters other than line terminators, as many as possible, then then match four digits and save the four digits in capture group 1".

Cary Swoveland
  • 106,649
  • 6
  • 63
  • 100
  • If the first example works it'll be very clever. Will test and report back. – Hashim Aziz Aug 13 '23 at 00:16
  • 1
    Nice use of `\K` to get rid of the capture group. The second solution is probably not worth keeping, the negative lookahead for `.*\d{4}` really blows out the steps when you get a really long string with more than one 4 digit sequence – Nick Aug 13 '23 at 01:08
  • @Nick, I agree. Thanks. – Cary Swoveland Aug 13 '23 at 01:25