I guess that if you want to get only the numbers, so I'd do this:
SQL> col download_speed for 999999 heading "download_speed"
SQL> col upload_speed for 999999 heading "upload_speed"
SQL> SELECT regexp_replace(regexp_substr('My ADSL 14Mbps/2M speed','[^\/]+'),'[^0-9]', '') download_speed
,regexp_replace(regexp_substr('My ADSL 14Mbps/2M speed','[^\/]+$'), '[^0-9]', '') upload_speed FROM dual;
do u
-- -
14 2
However, if you want to transpose the columns to rows, as you show in your expected result, I would do :
select *
from (
SELECT regexp_replace(regexp_substr('My ADSL 14Mbps/2M speed','[^\/]+'),'[^0-9]', '') download_speed
,regexp_replace(regexp_substr('My ADSL 14Mbps/2M speed','[^\/]+$'), '[^0-9]', '') upload_speed
FROM dual
) unpivot include nulls ( val for col in (download_speed,upload_speed) );
COL VA
-------------- --
DOWNLOAD_SPEED 14
UPLOAD_SPEED 2
You can change the values of COL and VA for the labels you want