I don't know is it worth it, but it is possible.
Try with:
(12.(3[3-9]|[4-9]\d))|(13(.([0-3]\d|4[01]))?)
it means:
12. -- starts with '12.',
3[3-9] -- 3 followed by digit from range 3 to 9 (33-39),
| -- OR
[4-9]\d -- digit from range 4 to 9 followed by any digit (40-99),
| -- OR
13 -- starts with '13'
. -- dot
[0-3]\d -- digit from range 0 to 3 followed by any digit,
| -- OR
4[01] -- 4 followed by 0 or 1,
? -- zero or one time
and (.([0-3]\d|4[01]))? is treated as a one group, to allow '13', but not '13.'
It will match numbers like: 12.33, 12.99, 13.41 ,13 ,12.41 ,13.39 ,etc.
and will ignore: 12.32, 13.42, etc.
Your code didn't work because:
(12.[3-9][3-9]|13.?[0-4][0-1]?)\d{0,2}
[3-9][3-9] - allows only numbers from ranges (33-39,43-49,53-59,...),
[0-4][0-1] - allows only numbers (00,01,10,11,20,21,30,31,40,41),
so there is huge omitted range