1

I'm trying to get the a regex running for the following type of strings: one upper case letter followed by a numeric value. The string can consist of multiple of these letter-numeric-value combinations. Here some examples and my expected output:

A12B8Y9CC10
-> output [0 => 12, 1 => 8, 2 => 9] (10 is ignored, because there are two letters)
V5C8I17
-> output [0 => 5, 1 => 8, 2 => 17]
KK18II9
-> output [] (because KK and II are always two letters followed by numeric values)
I8VV22ZZ4S9U2
-> output [0 => 8, 1 => 9, 2 => 2] (VV and ZZ are ignored)
A18Z12I
-> output [0 => 18, 1 => 12] (I is ignored, because no numeric value follows)

I tried to reach this by the following regex using preg_match: /^([A-Z]{1}\d{1,)$/

But it doesn't give the expected output. Can you please help me, how to solve this?

Thanks and best regards!

anubhava
  • 761,203
  • 64
  • 569
  • 643
Balu
  • 37
  • 1
  • 5

2 Answers2

3

You may use this regex in php using preg_match_all:

preg_match_all('/(?<![a-zA-Z])[a-zA-Z]\K\d+/', $string, $matches);

Resulting in array $matches[0] to return all the matches.

RegEx Demo

RegEx Details:

  • (?<![a-zA-Z]): Make sure we don't have a letter before current position
  • [a-zA-Z]: Match a letter
  • \K: Reset match info
  • \d+: Match 1+ digits
The fourth bird
  • 154,723
  • 16
  • 55
  • 70
anubhava
  • 761,203
  • 64
  • 569
  • 643
  • 1
    Thanks a lot anubhava! Works great. Only the left bracket is missing in the code you posted. Must look like that: preg_match_all('/(?<![a-zA-Z])[a-zA-Z]\K\d+/', $string, $matches); Thanks and best regards! – Balu Jun 25 '20 at 13:17
3

Another variant could be using SKIP FAIL to skip matches that do not qualify.

[A-Z]{2,}\d+(*SKIP)(*FAIL)|[A-Z](\d+)

Explanation

  • [A-Z]{2,}\d+ Match 2 or more uppercase chars A-Z and 1+ digits
  • (*SKIP)(*FAIL) Use SKIP FAIL to avoid matching
  • | Or
  • [A-Z](\d+) Match a single char A-Z and capture in group 1 one or more digits

Regex demo | Php demo

The matches are the first capturing group.

$pattern = '/[A-Z]{2,}\d+(*SKIP)(*FAIL)|[A-Z](\d+)/';
preg_match_all($pattern, $string, $matches);
print_r($matches[1]);

Or with the \K as in anubhava's answer

[A-Z]{2,}\d+(*SKIP)(*FAIL)|[A-Z]\K\d+

Regex demo | php demo

The fourth bird
  • 154,723
  • 16
  • 55
  • 70