The function text_replace is a one-string
tool which can be used to process a text
file using higher level functions which
operate on files.
The function text_replace has the various
incantations:
text_replace(snew,sold,string)
replaces all *distinct* text substrings
by snew and returns a new string.
text_replace(snew,sold,string, distinct)
does exactly the same thing.
text_replace(snew,sold,string, all)
replaces *all* text substrings sold,
whether or not they are separate words.
text_replace(snew,sold,string, 2)
replaces the *2nd* substring sold
found in string using the 'all' mode.
text_replace calls sloc and sword. (see below)
------------------------
Example of use:
(%i1) (display2d:false)$
(%i2) load(replace);
(%o2) "c:/work2/replace.mac"
(%i3) ls : "This is line one isn't it?"$
(%i4) text_replace ("was","is",ls,1);
(%o4) "Thwas is line one isn't it?"
(%i5) text_replace ("was","is",ls,2);
(%o5) "This was line one isn't it?"
(%i6) text_replace ("was","is",ls,3);
(%o6) "This is line one wasn't it?"
(%i7) text_replace ("was","is",ls,4);
" string does not contain that many substrings"
(%o7) "This is line one isn't it?"
(%i8) text_replace ("was","is",ls);
(%o8) "This was line one isn't it?"
(%i9) text_replace ("was","is",ls,distinct);
(%o9) "This was line one isn't it?"
(%i10) text_replace ("was","is",ls,all);
(%o10) "Thwas was line one wasn't it?"
----------------------------------------
text_replace code:
-------------------------------------
text_replace ([%w]) :=
block ([sn,so,as,%mode:distinct,lso,lsn,nloc,n1,as1],
sn : part (%w,1),
so : part (%w,2),
as : part (%w,3),
if length (%w) > 3 then
%mode : part (%w,4),
if listp (%mode) then
(disp (" fourth arg cannot be a list "),
return (as)),
if integerp (%mode) then
(nloc : sloc (as,so,%mode),
if not nloc then (
disp (" string does not contain that many substrings"),
return (as)),
return (ssubstfirst (sn,so,as,nloc))),
if %mode = all then
return (ssubst (sn,so,as)),
/* case only subst for distinct separate
words (the default case) */
lso : slength(so),
lsn : slength(sn),
n1 : sword (as,so,1),
if not n1 then return (as),
as1 : ssubstfirst(sn,so,as,sequal,n1,n1+lso),
/* is that the end of the string as1? */
if n1 + lsn -1 = slength (as1) then return (as1),
do (
n1 : sword (as1,so,n1+lsn),
if not n1 then return(),
as1 : ssubstfirst(sn,so,as1,sequal,n1,n1+lso),
if n1 + lsn -1 = slength(as1) then return()),
as1)$
----------------------------------------------------
text_replace calls sloc.
sloc (string, substring, n) finds the
string position of the n'th appearance of
the substring, ignoring distinctness.
Returns false if no n'th appearance.
(%i11) sloc (ls,"is",1);
(%o11) 3
(%i12) sloc (ls,"is",2);
(%o12) 6
(%i13) sloc (ls,"is",3);
(%o13) 18
(%i14) sloc (ls,"is",4);
(%o14) false
code:
------------------------------------
sloc(bs,bo,bn) :=
block ([lbs,lbo,nbs,nsearch:0 ],
lbs : slength (bs),
lbo : slength (bo),
/* search for first substring location */
nbs : ssearch (bo,bs,sequal,1),
nsearch : nsearch + 1,
if not nbs then return (false),
if nsearch = bn then return (nbs),
if nbs + lbo -1 = lbs then return(false),
do
(nsearch : nsearch + 1,
nbs : ssearch (bo,bs,sequal,nbs+1),
if not nbs then return(),
if nsearch = bn then return(),
if nbs + lbo -1 = lbs then return()),
nbs)$
-----------------------------------------
text_replace also calls sword, whose code is:
------------------------------------------------
/************************ sword ***********************/
/* sword(string,substring,nstart)
starts search at char pos nstart
and
returns false if text substring is not
found or if text substring is found but
is not a separate word.
Otherwise returns the postion
of the start of the first text substring
found.
sword calls sword1.
*/
sword (%ls,%ss,%nstart) :=
block ([%ln,%sl,%ns,%nnew,%sep ],
%ln : slength (%ls),
%sl : slength (%ss),
%ns : ssearch (%ss,%ls,sequal,%nstart),
/* if substring is not found in
the string beginning the
search at %nstart, ssearch returns
false */
if not %ns then return(false),
/* here we know %ns is some integer
and is the position of the first
substring found so far */
/* check if it is a separate word */
%sep : sword1 (%ls,%ns,%sl),
if %sep then return(%ns),
/* is substring found at end of the line? */
if %ns + %sl -1 = %ln then return (false),
/* search for possible next substring */
%nnew : %ns + 1,
do
(%ns : ssearch (%ss,%ls,sequal,%nnew),
if not %ns then return(),
if sword1(%ls,%ns,%sl) then return(),
if %ns + %sl -1 = %ln then (
%ns : false,
return())
else %nnew : %ns + 1),
%ns)$
--------------------------
finally, sword calls sword1, whose code is:
----------------------
/*************** sword1 ***********************/
/* sword1(string,nbegin,nlength) returns either
true or false depending on whether the text substring
(beginning at nbegin and having length nlength)
is a separate word. */
sword1 (%ms,%p,%q) :=
block ([%sleft:false,%sright:false ],
/* check left hand side of substring */
if (%p = 1) or (not alphanumericp (charat (%ms,%p - 1)))
then %sleft : true,
/* now check right hand side */
if (%p + %q - 1 = slength (%ms)) or
(not alphanumericp (charat (%ms,%p + %q)))
then %sright : true,
if %sleft and %sright then true else false )$
------------------------------------------
Ted Woollett