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
11 import com.stevesoft.pat.wrap.StringWrap;
\r
13 /** Internally used class. */
\r
16 RegHolder prev = null;
\r
19 /** Internally used class.
\r
25 CodeVal(int p,char c) {
\r
29 public String toString() {
\r
30 return "("+pos+","+code+")";
\r
35 To use this class, first use either the getReplacer() method from
\r
36 Transformer or Regex. You can then use replaceAll, replaceFirst,
\r
37 etc. methods on the Replacer in the same way that you can from
\r
38 either of those two classes.
\r
40 The only potential difference between using the methods of
\r
41 Replacer to do the replacing is that Replacer remembers changes
\r
42 to the replacing object between calls to replaceAll, replaceFirst
\r
43 etc. For details, see the example file
\r
44 <a href="http://javaregex.com/code/trans3.java.html">trans3.java</a>.
\r
45 @see com.stevesoft.pat.Transformer
\r
46 @see com.stevesoft.pat.Regex
\r
48 public class Replacer {
\r
51 /** Instantiate a new Replacer. */
\r
52 public Replacer() {}
\r
54 public StringLike replaceFirstRegion(String s,Regex r,
\r
55 int start,int end) {
\r
56 return replaceFirstRegion(new StringWrap(s),r,start,end);
\r
58 /** This method replaces the first occurence of the Regex in the
\r
59 String starting with position pos
\r
60 according to the Replacer rule of this object. */
\r
61 public StringLike replaceFirstRegion(StringLike s,Regex r,
\r
62 int start,int end) {
\r
66 return dorep(s,start,end);
\r
68 public StringLike replaceFirst(StringLike s) {
\r
69 return replaceFirstRegion(s,0,s.length());
\r
71 public StringLike replaceFirstFrom(StringLike s,int start) {
\r
72 return replaceFirstRegion(s,start,s.length());
\r
74 public StringLike replaceFirstRegion(StringLike s,int start,int end) {
\r
76 return dorep(s,start,end);
\r
79 RegHolder rh = new RegHolder();
\r
81 public StringLike replaceAllRegion(String s,Regex r,
\r
82 int start, int end) {
\r
83 return replaceAllRegion(new StringWrap(s),r,start,end);
\r
85 /** This method replaces all occurences of the Regex in the
\r
86 String starting with postition pos
\r
87 according to the Replacer rule of this object. */
\r
88 public StringLike replaceAllRegion(StringLike s,Regex r,
\r
89 int start,int end) {
\r
94 return dorep(s,start,end);
\r
96 public StringLike replaceAll(StringLike s) {
\r
97 return replaceAllRegion(s,0,s.length());
\r
99 public StringLike replaceAllFrom(StringLike s,int start) {
\r
100 return replaceAllRegion(s,start,s.length());
\r
102 public StringLike replaceAllRegion(StringLike s,int start,int end) {
\r
104 return dorep(s,start,end);
\r
107 public String replaceAll(String s) {
\r
108 return replaceAllRegion(new StringWrap(s),0,s.length()).toString();
\r
110 public String replaceAllFrom(String s,int start) {
\r
111 return replaceAllRegion(new StringWrap(s),start,s.length()).toString();
\r
113 public String replaceAllRegion(String s,int start,int end) {
\r
115 return dorep(new StringWrap(s),start,end).toString();
\r
118 final public boolean isSpecial(ReplaceRule x) {
\r
120 if(x instanceof SpecialRule
\r
121 || (x instanceof RuleHolder && ((RuleHolder)x).held instanceof SpecialRule))
\r
127 final public void apply1(RegRes rr) {
\r
128 rr.charsMatched_++;
\r
130 rr.charsMatched_--;
\r
133 final StringLike dorep(StringLike s,int start,int end) {
\r
134 StringLike ret = s;
\r
135 want_more_text = false;
\r
138 throw new NullPointerException("Replacer has null Regex pointer");
\r
139 if(rh.me._search(s,start,end)) {
\r
140 int rmn = rh.me.matchedTo();
\r
141 if(rh.me.charsMatched()==0 && !isSpecial(rh.me.getReplaceRule())) {
\r
148 !want_more_text && rh.me._search(s,i,end);i=rmn) {
\r
149 rmn = rh.me.matchedTo();
\r
150 if(rh.me.charsMatched()==0) {
\r
151 if(!isSpecial(rh.me.getReplaceRule()))
\r
158 ret = ret == null ? s : ret;
\r
163 StringBufferLike sb = null;
\r
164 StringLike src = null;
\r
166 /** This method allows you to apply the results of several
\r
167 matches in a sequence to modify a String of text. Each
\r
168 call in the sequence must operate on the same piece of
\r
169 text and the matchedFrom() of each RegRes given to this
\r
170 method must be greater in value than the preceeding
\r
171 RegRes's matchedTo() value.
\r
173 public void apply(RegRes r,ReplaceRule rp) {
\r
174 if(rp==null ||(rp.next == null && rp instanceof AmpersandRule))
\r
178 src = r.getStringLike();
\r
180 sb = new StringBufferLike(src.newStringBufferLike());
\r
181 int rmf = r.matchedFrom();
\r
182 for(int ii=pos;ii<rmf;ii++)
\r
183 sb.append(src.charAt(ii));
\r
185 Vector v = new Vector();
\r
186 for(ReplaceRule x=rp;x != null;x=x.next) {
\r
188 if(x instanceof SpecialRule) {
\r
189 if(x instanceof WantMoreTextReplaceRule
\r
190 && want_more_text_enable)
\r
191 want_more_text = true;
\r
192 else if(x instanceof PushRule) {
\r
193 RegHolder rh2 = new RegHolder();
\r
194 rh2.me = ( (PushRule)x ).NewRule;
\r
197 } else if(x instanceof PopRule) {
\r
198 if(rh.prev != null)
\r
200 } else if(x instanceof ChangeRule) {
\r
201 rh.me = ( (ChangeRule) x).NewRule;
\r
205 if(!want_more_text)
\r
206 pos = r.matchedTo();
\r
209 boolean want_more_text = false, want_more_text_enable = false;
\r
210 public boolean WantMoreText() { return want_more_text; }
\r
211 /** Another form of apply, it is the same as
\r
212 apply(r,r.getReplaceRule()). */
\r
213 public void apply(Regex r) { apply(r,r.getReplaceRule()); }
\r
215 /** This finishes the replacement, appending the right() part of
\r
216 the last RegRes given to substitute(RegRes). After this method
\r
217 is called, the Replace object is reset to perform another
\r
218 substitution. If no RegRes objects with a true didMatch are
\r
219 applied, this returns null. */
\r
220 public StringLike finish() {
\r
223 //sb.append(src.substring(pos,src.length()));
\r
224 int s_end = src.length();
\r
225 for(int ii=pos;ii<s_end;ii++)
\r
226 sb.append(src.charAt(ii));
\r
228 lastMatchedTo = pos;
\r
230 StringLike retstr = sb.toStringLike();
\r
234 int lastMatchedTo = 0;
\r
235 public Object clone() {
\r
236 Replacer r = new Replacer();
\r
241 r.lastMatchedTo = lastMatchedTo;
\r
242 r.want_more_text = want_more_text;
\r
243 r.want_more_text_enable = want_more_text_enable;
\r
245 r.rh.prev = rh.prev;
\r
248 public int lastMatchedTo() { return lastMatchedTo; }
\r
249 public Regex getRegex() {
\r
252 public void setSource(StringLike sl) {
\r
255 public void setBuffer(StringBufferLike sbl) {
\r
258 public void setPos(int pos) {
\r