f: func [t][
a: charset [not "[]"] ; all chars except [ and ]
while [ parse t [ ; repeat while parse is returning true
any a ; 0 or more chars other than [ and ]
some [ ; one or more block:
remove ["[" copy h any a "]" copy d a] ; remove the entire block, store the
; substring between the [] in h,
; the digit into d
(insert/dup v: copy "" h to-integer d) ; makes d copies of h
insert v ; and inserts them in place
| skip ] ; skip if no match
]
][] ; empty block for 'while'
]
I started learning Red's Parse dialect only yesterday, so I'm sure my code can be improved further. Parse is incomparably more verbose then regex, but is very clear and readable and can be freely mixed with the rest of the Red language.
I don't know why the test case [!@#[$%^[&*(]2]2]2 crashes my code (I suppose because of the ^[ string)