I got the solution from here by using CTE recursively to strip out the string
declare @str nvarchar(100)='get all substrings #image:header# #image:footer# between specific characters'
declare @imageTokenStart nvarchar(8)='#image:'
declare @imageTokenEnd nvarchar(1)='#'
;WITH cte(msg,token)
as
(
SELECT RIGHT(msg,(LEN(msg)- CHARINDEX(@imageTokenEnd, msg, CHARINDEX(@imageTokenStart, msg, 0) + 1)))
,SUBSTRING(msg, CHARINDEX(@imageTokenStart, msg, 0) + LEN(@imageTokenStart)
, CHARINDEX(@imageTokenEnd, msg, CHARINDEX(@imageTokenStart, msg, 0) + 1) - (
CHARINDEX(@imageTokenStart, msg, 0) + LEN(@imageTokenStart)))
FROM (SELECT @str as msg) tmp
WHERE CHARINDEX(@imageTokenStart,msg,0)>0
UNION ALL
SELECT RIGHT(msg,(LEN(msg)- CHARINDEX(@imageTokenEnd,msg,CHARINDEX(@imageTokenStart, msg, 0) + 1)))
,SUBSTRING(msg, CHARINDEX(@imageTokenStart, msg, 0) + LEN(@imageTokenStart)
, CHARINDEX(@imageTokenEnd, msg,
CHARINDEX(@imageTokenStart, msg, 0) + 1) - (CHARINDEX(@imageTokenStart, msg, 0) + LEN(@imageTokenStart)))
FROM cte
WHERE CHARINDEX(@imageTokenStart,msg,0)>0
)
SELECT token FROM cte
Result
header
footer