Corrected version to fix a bug in the application of the escape
character:
load 'regex'
NB.
----------------------------------------------------------------------------
NB. rxsubst - Regular expression substitution
NB.
NB. str =. ((pattern[;index]);newtext) rxsubst str
NB.
NB. Back references (e.g. '\1') in the replacement text are supported.
NB. For example: ('\([biu]){(.*?)}';'<\1>\2</\1>') rxsubst '@[EMAIL PROTECTED]
and @[EMAIL PROTECTED]
'
NB.
NB. Brian B. McGuinness J April, 2008
NB.
----------------------------------------------------------------------------
rxsubst =: 4 : 0
pat=. >{.x
new=. >{:x
if. L. pat do. 'pat ndx'=. pat else. ndx=. ,0 end.
if. 1 ~: #$ ndx do. 13!:8[3 end.
NB. --- rxmatches returns an MxNx2 array with the starting location
and
NB. length of the search string and each search substring, in
order.
NB. M is the number of matches and N is 1 + the number of
substrings.
mat=. pat rxmatches y
if. 0 = # mat do.
y
return.
end.
NB. --- Find any back references in the replacement text
escaped =. 0
newtxt =. 0 2 $ 0
token =. ''
for_i. i. # new do.
c =. i { new
if. escaped do.
d =. '123456789' i. c
if. d < 9 do.
newtxt =. newtxt, token; d
token =. ''
else.
token =. token, c
end.
escaped =. 0
else.
if. c = '\' do.
escaped =. 1
else.
token =. token, c
end.
end.
end.
if. 0 < #token do.
newtxt =. newtxt, token; 9
end.
if. 1 = #newtxt do.
NB. --- No back references in the replacement text; act like
rxrplc
(0 { newtxt) (({.ndx) {"2 mat) rxmerge y
else.
NB. --- Expand the back references
repl =. ''
for_i. mat do.
a =. ''
for_j. }. i do.
a =. a, < (1 { j) {. (0 { j) }. y
end.
a =. ;((1 {::"1 newtxt) { 10 {. a) (< a: ; 1) } newtxt
repl =. repl, <a
end.
NB. --- Now perform the replacements
repl (({.ndx) {"2 mat) rxmerge y
end.
)


|