1;
2;+
3; NAME:
4;       STRTRANS
5; PURPOSE:
6;       Translate all occurences of one substring to another.
7; CATEGORY:
8;       text/strings
9; CALLING SEQUENCE:
10;       new = strtrans(oldstr,from,to,ned)
11; INPUTS:
12;       oldstr -- string on which to operate.              in
13;                 May be an array.
14;       from   -- substrings to be translated. May be      in
15;                 an array.
16;       to     -- what strings in from should be           in
17;                 translated to. May be an array.
18; KEYWORD PARAMETERS:
19;       /HELP  -- Set this to print useful message and
20;                 exit.
21; OUTPUTS:
22;       new    -- Translated string. Array if oldstr is    out
23;                 an array.
24;       ned    -- number of substitutions performed in     out
25;                 oldstr.  Array if oldstr is an array.
26; COMMON BLOCKS:
27; SIDE EFFECTS:
28; NOTES:
29;       - Any of old, from, and to can be arrays.
30;       - from and to must have the same number of elements.
31; EXAMPLE:
32;       inp='Many*bad!chars+in_here'
33;       from=['*','!','+','_']
34;       to  =[' ',' ',' ',' ']
35;       out = strtrans(inp,from,to,ned)
36;       Will produce out='Many bad chars in here', and set ned to 4.
37; MODIFICATION HISTORY:
38;       $Id: strtrans.pro,v 1.7 2004/06/15 17:25:54 mcraig Exp $
39;       $Log: strtrans.pro,v $
40;       Revision 1.7  2004/06/15 17:25:54  mcraig
41;       Fixed bug in regular expression, changed array notation to square brackets
42;
43;       Revision 1.6  2004/01/11 01:49:00  mcraig
44;       Changed format of one array to newer [] style to avoidf conflict with function name in astro library.
45;
46;       Revision 1.5  2001/11/23 21:14:35  mcraig
47;       Added keywords /EXTRACT, /PRESERVE_NULL, /REGEX to call to
48;       strsplit. This comes very close to reproducing the behavior of the
49;       obsolete routine str_sep.
50;
51;       Revision 1.4  2001/11/21 19:13:23  mcraig
52;       Changed str_sep to strsplit. The former is now considered obsolete by RSI.
53;
54;       Revision 1.3  1996/06/14 20:00:27  mcraig
55;       Updated Copyright info.
56;
57;       Revision 1.2  1996/05/09 00:22:17  mcraig
58;       Sped up significantly by using str_sep to handle the translation.  No longer
59;       relies on routines fromother user libraries.
60;
61;       Revision 1.1  1996/01/31 18:47:37  mcraig
62;       Initial revision
63;
64; RELEASE:
65;       $Name: Rel_2_1_2 $
66;
67; COPYRIGHT:
68;  Copyright (C) 1996 The Regents of the University of California, All
69;  Rights Reserved.  Written by Matthew W. Craig.
70;  See the file COPYRIGHT for restrictions on distrubting this code.
71;  This code comes with absolutely NO warranty; see DISCLAIMER for details.
72;-
73;
74FUNCTION strtrans, InputString, from, to, ned,  $
75                   HELP=Help
76
77; Bomb out to caller if error.
78    On_error, 2
79
80; Offer help if we don't have at least InputString, from, and to, or
81; if the user asks for it.
82    IF (n_params() LT 3) OR keyword_set(help) THEN BEGIN
83        offset = '   '
84        print, offset+'Translate all occurences of one substring to another.'
85        print, offset+'new = strtrans(oldstr,from,to,ned)'
86        print, offset+'Inputs:'
87        print, offset+offset+'oldstr -- string on which to operate.              in'
88        print, offset+offset+'          May be an array.'
89        print, offset+offset+'from   -- substrings to be translated. May be      in'
90        print, offset+offset+'          an array.'
91        print, offset+offset+'to     -- what strings in from should be           in'
92        print, offset+offset+'          translated to. May be an array.'
93        print, offset+'Outputs:'
94        print, offset+offset+'new    -- Translated string. Array if oldstr is    out'
95        print, offset+offset+'          an array.'
96        print, offset+offset+'ned    -- number of substitutions performed in     out'
97        print, offset+offset+'          oldstr.  Array if oldstr is an array.'
98        print, offset+'Notes:'
99        print, offset+offset+'- Any of old, from, and to can be arrays. '
100        print, offset+offset+'- from and to must have the same number of elements.'
101        return, -1
102    ENDIF
103
104    strn = InputString
105
106;  Check that From/To have same number of elements.  RETURN if they don't.
107    NFrom = n_elements(from)
108    NTo = n_elements(to)
109    IF (NFrom EQ 0) OR (NTo EQ 0) THEN return, strn
110    IF NFrom NE NTo THEN BEGIN
111        print,'Error: Number of elements in from/to unequal'
112        return,-1
113    ENDIF
114
115;  Make sure there are no null strings in From.  RETURN if there are.
116    FromLen = strlen(From)
117    IF (total(FromLen EQ 0) GT 0) THEN BEGIN
118        print, 'Error: elements of From must have nonzero length.'
119        return, -1
120    ENDIF
121
122    NStrings = n_elements(strn)
123    ned = lonarr(NStrings)
124    tmpned = 0L
125
126; Say strn='a#b#c', from='#' and to='@'.  Then the approach here is to
127; first split strn at all occurances of '#', then recombine the pieces
128; with '@' inserted instead.  Do this for all elements of strn, and
129; all elements of from.
130    FOR i = 0L, NStrings-1 DO BEGIN
131        ned[i] = 0L
132        FOR j=0L, NFrom-1 DO BEGIN
133            SepStr = strsplit(strn[i], from[j], $
134                              /EXTRACT, /REGEX, /PRESERVE_NULL)
135            NSubs = n_elements(SepStr) - 1
136            strn[i] = SepStr[0]
137            FOR k=1L, NSubs DO strn[i] = strn[i] + To[j] + SepStr[k]
138            ned[i] =  ned[i] + NSubs
139        ENDFOR
140    ENDFOR
141
142    return, strn
143END
144