View/Edit #29:subst*itute

Switch to edit mode.

Name(s): subst*itute
1:  "subst(string,{{redex1,repl1},{redex2,repl2},{redex3,repl3}...}[,case])"
2:  "  => returns string with all instances of the strings redex<n> replaced respectively by the strings repl<n>.  If the optional argument `case' is given and nonzero, the search for instances of redex<n> is case sensitive."
3:  "  Substitutions are done in parallel, i.e., instances of redex<n> that appear in any of the replacement strings are ignored.  In the event that two redexes overlap, whichever is leftmost in `string' takes precedence.  For two redexes beginning at the same position, the longer one takes precedence."
4:  ""
5:  "subst(\"hoahooaho\",{{\"ho\",\"XhooX\"},{\"hoo\",\"mama\"}}) => \"XhooXamamaaXhooX\""
6:  "subst(\"Cc: banana\",{{\"a\",\"b\"},{\"b\",\"c\"},{\"c\",\"a\"}},1) => \"Ca: cbnbnb\""
7:  ""
8:  "Beware!  The second argument to this verb is a list; even if only one "
9:  "redex is provided, it must be in (a one-element) list."
10: if (typeof(ostr = args[1]) != $STR)
11:   return ostr
12: endif
13: case = {@args, 0}[3]
14: len = length(ostr)
15: " - - - find the first instance of each substitution - -"
16: indices = {}
17: substs = {}
18: for s in (args[2])
19:   if (i = index(ostr, s[1], case))
20:     fi = $list_utils:find_insert(indices, i = i - len) - 1
21:     while (fi && (indices[fi] == i && length(substs[fi][1]) < length(s[1])))
22:       "...give preference to longer redexes..."
23:       fi = fi - 1
24:     endwhile
25:     indices = listappend(indices, i, fi)
26:     substs = listappend(substs, s, fi)
27:   endif
28: endfor
29: "- - - - - perform substitutions - "
30: nstr = ""
31: while (substs)
32:   ind = len + indices[1]
33:   sub = substs[1]
34:   indices = listdelete(indices, 1)
35:   substs = listdelete(substs, 1)
36:   if (ind > 0)
37:     nstr = nstr + ostr[1..ind - 1] + sub[2]
38:     ostr = ostr[ind + length(sub[1])..len]
39:     len = length(ostr)
40:   endif
41:   if (next = index(ostr, sub[1], case))
42:     fi = $list_utils:find_insert(indices, next = next - len) - 1
43:     while (fi && (indices[fi] == next && length(substs[fi][1]) < length(sub[1])))
44:       "...give preference to longer redexes..."
45:       fi = fi - 1
46:     endwhile
47:     indices = listappend(indices, next, fi)
48:     substs = listappend(substs, sub, fi)
49:   endif
50: endwhile
51: return nstr + ostr
52: "Last modified by Dax (#789) on Mon Aug  7 21:32:55 2006 MDT."

Verb arguments: this none this
Verb perms: Readable eXecutable NOT-Debug
Verb owned by: Hacker (#60)

You are not logged in.

[home | help | who | search | setup | code]