2 // This software is now distributed according to
\r
3 // the Lesser Gnu Public License. Please see
\r
4 // http://www.gnu.org/copyleft/lesser.txt for
\r
6 // -- Happy Computing!
\r
8 package com.stevesoft.pat;
\r
10 import jalview.util.MessageManager;
\r
12 import com.stevesoft.pat.wrap.*;
\r
15 * Replacement rule used by the Transformer.
\r
17 * @see com.stevesoft.pat.Transformer
\r
19 class TransRepRule extends ReplaceRule
\r
23 TransRepRule(Transformer t)
\r
28 public String toString1()
\r
33 public Object clone1()
\r
35 return new TransRepRule(t);
\r
38 public void apply(StringBufferLike sb, RegRes rr)
\r
40 // get the ReplaceRule of the Regex that matched.
\r
41 next = t.tp.ra[t.tp.pn].getReplaceRule();
\r
46 * Sometimes you want to replace a whole bunch of things that might occur within
\r
47 * a single line of text. One efficient way to do this, both in terms of
\r
48 * performance and programming ease, is with Transformer. The Transformer
\r
49 * contains an array of Regex's and uses the Regex that matches earliest within
\r
50 * the text to do the replacing, if two Regex's match at the same time it uses
\r
51 * the one put in the Transformer first.
\r
53 * This feature can be used to prevent transformations from occurring in certain
\r
54 * regions. For example, if I add the rule s'//.*'$&' and then add the rule
\r
55 * s/hello/goodbye/ the Transformer will replace "hello" with "goodbye" except
\r
56 * when it occurs inside a double-slash style of comment. The transformation on
\r
57 * the comment goes first, does nothing, and precludes transformation on the
\r
58 * same region of text as the s/hello/goodbye/ rule.
\r
60 * So far, at least, this class does not have the capability of turning into a
\r
63 public class Transformer
\r
67 Regex rp = new Regex();
\r
69 boolean auto_optimize;
\r
72 * Get a replacer to that works with the current Regex.
\r
74 * @see com.stevesoft.pat.Replacer
\r
76 public Replacer getReplacer()
\r
78 return rp.getReplacer();
\r
81 /** Instantiate a new Transformer object. */
\r
82 public Transformer(boolean auto)
\r
84 auto_optimize = auto;
\r
85 tp = new TransPat();
\r
86 rp.setReplaceRule(new TransRepRule(this));
\r
90 /** Add a new Regex to the set of Regex's. */
\r
91 public void add(Regex r)
\r
97 tp.ra[tp.ra_len++] = r;
\r
98 if (tp.ra.length == tp.ra_len)
\r
100 Regex[] ra2 = new Regex[tp.ra_len + 10];
\r
101 for (int i = 0; i < tp.ra_len; i++)
\r
107 rp.numSubs_ = r.numSubs_ > rp.numSubs_ ? r.numSubs_ : rp.numSubs_;
\r
110 /** Returns the number of Regex's in this Transformer. */
\r
111 public int patterns()
\r
116 /** Get the Regex at position i in this Transformer. */
\r
117 public Regex getRegexAt(int i)
\r
119 if (i >= tp.ra_len)
\r
121 throw new ArrayIndexOutOfBoundsException("i=" + i + ">=" + patterns());
\r
125 throw new ArrayIndexOutOfBoundsException("i=" + i + "< 0");
\r
130 /** Set the Regex at position i in this Transformer. */
\r
131 public void setRegexAt(Regex rx, int i)
\r
133 if (i >= tp.ra_len)
\r
135 throw new ArrayIndexOutOfBoundsException("i=" + i + ">=" + patterns());
\r
139 throw new ArrayIndexOutOfBoundsException("i=" + i + "< 0");
\r
145 * Add a new Regex by calling Regex.perlCode
\r
147 * @see com.stevesoft.pat.Regex#perlCode(java.lang.String)
\r
149 public void add(String rs)
\r
151 Regex r = Regex.perlCode(rs);
\r
154 throw new NullPointerException(MessageManager.formatMessage("exception.bad_pattern_to_regex_perl_code", new String[]{rs}));
\r
160 * Add an array of Strings (which will be converted to Regex's via the
\r
161 * Regex.perlCode method.
\r
163 * @see com.stevesoft.pat.Regex#perlCode(java.lang.String)
\r
165 public void add(String[] array)
\r
167 for (int i = 0; i < array.length; i++)
\r
173 /** Replace all matches in the current String. */
\r
174 public String replaceAll(String s)
\r
176 return dorep(s, 0, s.length());
\r
179 public StringLike replaceAll(StringLike s)
\r
181 return dorep(s, 0, s.length());
\r
184 /** Replace all matching patterns beginning at position start. */
\r
185 public String replaceAllFrom(String s, int start)
\r
187 return dorep(s, start, s.length());
\r
191 * Replace all matching patterns beginning between the positions start and end
\r
194 public String replaceAllRegion(String s, int start, int end)
\r
196 return dorep(s, start, end);
\r
199 Replacer repr = new Replacer();
\r
201 final StringLike dorep(StringLike s, int start, int end)
\r
203 StringLike tfmd = repr.replaceAllRegion(s, rp, start, end);
\r
204 tp.lastMatchedTo = repr.lastMatchedTo;
\r
208 final String dorep(String s, int start, int end)
\r
210 return dorep(new StringWrap(s), start, end).toString();
\r
213 /** Replace the first matching pattern in String s. */
\r
214 public String replaceFirst(String s)
\r
216 return dorep(s, 0, s.length());
\r
220 * Replace the first matching pattern after position start in String s.
\r
222 public String replaceFirstFrom(String s, int start)
\r
224 return dorep(s, start, s.length());
\r
228 * Replace the first matching pattern that begins between start and end
\r
231 public String replaceFirstRegion(String s, int start, int end)
\r
233 return dorep(s, start, end);
\r