Here's one way of doing it:
WITH sample_data AS (select 'TX353 G35 1992' str from dual union all
select 'Ref QP141 B151 R4 1956' str from dual union all
select 'RM216 M285 K5 1996' str from dual union all
select 'T385 C22 1960' str from dual union all
select 'Ths LB500 M200 A5 1998' str from dual union all
select 'X12345' str from dual union all
select 'Y F123' str from dual)
SELECT str,
regexp_substr(str, '([A-Z]{1,2})[[:digit:]]*( |$)', 1, 1, NULL, 1) sub_str
FROM sample_data;
STR SUB_STR
---------------------- ----------------------
TX353 G35 1992 TX
Ref QP141 B151 R4 1956 QP
RM216 M285 K5 1996 RM
T385 C22 1960 T
Ths LB500 M200 A5 1998 LB
X12345 X
Y F123 Y
This looks for the pattern of one or two upper case letters followed by 0 or more digits followed by a space or the end of the line. (If you want to restrict the number of digits to 1 or more, change the *
to a +
.)
We put brackets around the "one or two upper case letters" to label it as a subexpression, which we can then request to be output in the regexp_substr (that's the final parameter, which in our case is 1 because our desired subexpression is the first one encountered).
If you have other special characters that could follow your desired pattern, then you can simply expand the OR section (currently ( |$)
), e.g. if you wanted to include a question mark, the OR section would become ( |?|$)