You don't need regular expressions and can do this with simple string functions:
WITH bounds ( id, value, start_pos, end_pos ) AS (
SELECT id,
value,
INSTR( value, 'URL', 1, 1 ) + 3,
INSTR( value, 'URL', 1, 2 )
FROM table_name
UNION ALL
SELECT id,
value,
end_pos + 3,
INSTR( value, 'URL', end_pos + 3, 1 )
FROM bounds
WHERE end_pos > 0
)
SELECT id,
start_pos,
SUBSTR( value, start_pos, end_pos - start_pos ) AS url
FROM bounds
WHERE end_pos > 0
ORDER BY id, start_pos;
So, for the sample data:
CREATE TABLE table_name ( id, value ) AS
SELECT 1, 'ABCURLCBSURLDMSURLWER' FROM DUAL UNION ALL
SELECT 2, 'ABCURLURLDEFURLGHIURL' FROM DUAL;
This outputs:
ID | START_POS | URL
-: | --------: | :---
1 | 7 | CBS
1 | 13 | DMS
2 | 7 | null
2 | 10 | DEF
2 | 16 | GHI
db<>fiddle here
Option 2
If you did want to use regular expressions then you can use:
SELECT t.id,
x.COLUMN_VALUE AS url
FROM table_name t
CROSS APPLY TABLE(
CAST(
MULTISET(
SELECT REGEXP_SUBSTR(
t.value,
'(.*?)URL',
INSTR( t.value, 'URL' ) + 3,
LEVEL,
NULL,
1
)
FROM DUAL
CONNECT BY
LEVEL <= REGEXP_COUNT(
t.value, '(.*?)URL', INSTR( t.value, 'URL' ) + 3
)
)
AS SYS.ODCIVARCHAR2LIST
)
) x;
Which, for the same test data, outputs:
ID | URL
-: | :---
1 | CBS
1 | DMS
2 | null
2 | DEF
2 | GHI
db<>fiddle here