NB. Regular expressions extended for Perl-like substitution
NB. to do: \xHH
require'strings regex'
NB. =========================================================
NB.*rxmain v return ()-less mat from ()-ful pattern
rxmain=: ,:"1@:({."2)
NB. =========================================================
NB.*rxs v make Perl-like s/PAT/REPL/OPT substitution
NB. use:
NB. '/PAT/REPL/OPT' rsx str
NB. PAT - the usual POSIX pattern used in J regex
NB. REPL - the POSIX sed-like replacement string
NB. \1-\9 corresponding parens content
NB. \0 or & whole match
NB. \_ whole match in string representation (for 'e')
NB. \t TAB
NB. \n LF
NB. \r CR
NB. \f FF
NB. \other other
NB. OPT - any of 'ige' for ignore case, global, execute
NB. see: examples
rxs=: 4 : 0
esc=. {.x.
'pat rpl opt'=. 3{. <;._1 x.
str=. tolower^:('i'e. opt) y.
pat=. tolower^:('i'e. opt) pat
mat=. pat rxmatch`rxmatches@.('g'e. opt) str
if. (0=#mat) +. _1=1{.,mat do. y. return. end.
subs=. ,:^:(2: > #@$) mat rxfrom y.
mat=. rxmain mat
newr=. ''
for_i. i.#mat do.
if. 'e' e. opt do.
r=. rpl rplc '\\';esc
r=. r rplc '\n';'LF'
r=. r rplc '\r';'CR'
r=. r rplc '\t';'TAB'
r=. r rplc '\f';'FF'
r=. r rplc '&';5!:5<'t' [ t=. >(<i,0){subs
r=. r rplc '\_';'('&,@(,&')')@(5!:5) <'t' [ t=. i{subs
for_j. i.{:$subs do.
r=. r rplc ('\',":j);5!:5<'t' [ t=. >(<i,j){subs
end.
r=. r rplc '\';''
r=. r rplc esc;'\'
for_j. i.+/'e'E.opt do.
r=. (,@":@:".) :: ('__'"_) r
end.
else.
r=. rpl rplc '\\';esc
r=. r rplc '\n';LF
r=. r rplc '\r';CR
r=. r rplc '\t';TAB
r=. r rplc '\f';FF
r=. r rplc '&';>(<i,0){subs
for_j. i.{:$subs do.
r=. r rplc ('\',":j);>(<i,j){subs
end.
r=. r rplc '\';''
r=. r rplc esc;'\'
end.
newr=. newr,<r
end.
newr mat rxmerge y.
)