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 com.stevesoft.pat.wrap.StringWrap;
\r
12 /** Internally used class. */
\r
15 RegHolder prev = null;
\r
18 /** Internally used class.
\r
24 CodeVal(int p,char c) {
\r
28 public String toString() {
\r
29 return "("+pos+","+code+")";
\r
34 To use this class, first use either the getReplacer() method from
\r
35 Transformer or Regex. You can then use replaceAll, replaceFirst,
\r
36 etc. methods on the Replacer in the same way that you can from
\r
37 either of those two classes.
\r
39 The only potential difference between using the methods of
\r
40 Replacer to do the replacing is that Replacer remembers changes
\r
41 to the replacing object between calls to replaceAll, replaceFirst
\r
42 etc. For details, see the example file
\r
43 <a href="http://javaregex.com/code/trans3.java.html">trans3.java</a>.
\r
44 @see com.stevesoft.pat.Transformer
\r
45 @see com.stevesoft.pat.Regex
\r
47 public class Replacer {
\r
50 /** Instantiate a new Replacer. */
\r
51 public Replacer() {}
\r
53 public StringLike replaceFirstRegion(String s,Regex r,
\r
54 int start,int end) {
\r
55 return replaceFirstRegion(new StringWrap(s),r,start,end);
\r
57 /** This method replaces the first occurence of the Regex in the
\r
58 String starting with position pos
\r
59 according to the Replacer rule of this object. */
\r
60 public StringLike replaceFirstRegion(StringLike s,Regex r,
\r
61 int start,int end) {
\r
65 return dorep(s,start,end);
\r
67 public StringLike replaceFirst(StringLike s) {
\r
68 return replaceFirstRegion(s,0,s.length());
\r
70 public StringLike replaceFirstFrom(StringLike s,int start) {
\r
71 return replaceFirstRegion(s,start,s.length());
\r
73 public StringLike replaceFirstRegion(StringLike s,int start,int end) {
\r
75 return dorep(s,start,end);
\r
78 RegHolder rh = new RegHolder();
\r
80 public StringLike replaceAllRegion(String s,Regex r,
\r
81 int start, int end) {
\r
82 return replaceAllRegion(new StringWrap(s),r,start,end);
\r
84 /** This method replaces all occurences of the Regex in the
\r
85 String starting with postition pos
\r
86 according to the Replacer rule of this object. */
\r
87 public StringLike replaceAllRegion(StringLike s,Regex r,
\r
88 int start,int end) {
\r
93 return dorep(s,start,end);
\r
95 public StringLike replaceAll(StringLike s) {
\r
96 return replaceAllRegion(s,0,s.length());
\r
98 public StringLike replaceAllFrom(StringLike s,int start) {
\r
99 return replaceAllRegion(s,start,s.length());
\r
101 public StringLike replaceAllRegion(StringLike s,int start,int end) {
\r
103 return dorep(s,start,end);
\r
106 public String replaceAll(String s) {
\r
107 return replaceAllRegion(new StringWrap(s),0,s.length()).toString();
\r
109 public String replaceAllFrom(String s,int start) {
\r
110 return replaceAllRegion(new StringWrap(s),start,s.length()).toString();
\r
112 public String replaceAllRegion(String s,int start,int end) {
\r
114 return dorep(new StringWrap(s),start,end).toString();
\r
117 final public boolean isSpecial(ReplaceRule x) {
\r
119 if(x instanceof SpecialRule
\r
120 || (x instanceof RuleHolder && ((RuleHolder)x).held instanceof SpecialRule))
\r
126 final public void apply1(RegRes rr) {
\r
127 rr.charsMatched_++;
\r
129 rr.charsMatched_--;
\r
132 final StringLike dorep(StringLike s,int start,int end) {
\r
133 StringLike ret = s;
\r
134 want_more_text = false;
\r
137 throw new NullPointerException("Replacer has null Regex pointer");
\r
138 if(rh.me._search(s,start,end)) {
\r
139 int rmn = rh.me.matchedTo();
\r
140 if(rh.me.charsMatched()==0 && !isSpecial(rh.me.getReplaceRule())) {
\r
147 !want_more_text && rh.me._search(s,i,end);i=rmn) {
\r
148 rmn = rh.me.matchedTo();
\r
149 if(rh.me.charsMatched()==0) {
\r
150 if(!isSpecial(rh.me.getReplaceRule()))
\r
157 ret = ret == null ? s : ret;
\r
162 StringBufferLike sb = null;
\r
163 StringLike src = null;
\r
165 /** This method allows you to apply the results of several
\r
166 matches in a sequence to modify a String of text. Each
\r
167 call in the sequence must operate on the same piece of
\r
168 text and the matchedFrom() of each RegRes given to this
\r
169 method must be greater in value than the preceeding
\r
170 RegRes's matchedTo() value.
\r
172 public void apply(RegRes r,ReplaceRule rp) {
\r
173 if(rp==null ||(rp.next == null && rp instanceof AmpersandRule))
\r
177 src = r.getStringLike();
\r
179 sb = new StringBufferLike(src.newStringBufferLike());
\r
180 int rmf = r.matchedFrom();
\r
181 for(int ii=pos;ii<rmf;ii++)
\r
182 sb.append(src.charAt(ii));
\r
184 for(ReplaceRule x=rp;x != null;x=x.next) {
\r
186 if(x instanceof SpecialRule) {
\r
187 if(x instanceof WantMoreTextReplaceRule
\r
188 && want_more_text_enable)
\r
189 want_more_text = true;
\r
190 else if(x instanceof PushRule) {
\r
191 RegHolder rh2 = new RegHolder();
\r
192 rh2.me = ( (PushRule)x ).NewRule;
\r
195 } else if(x instanceof PopRule) {
\r
196 if(rh.prev != null)
\r
198 } else if(x instanceof ChangeRule) {
\r
199 rh.me = ( (ChangeRule) x).NewRule;
\r
203 if(!want_more_text)
\r
204 pos = r.matchedTo();
\r
207 boolean want_more_text = false, want_more_text_enable = false;
\r
208 public boolean WantMoreText() { return want_more_text; }
\r
209 /** Another form of apply, it is the same as
\r
210 apply(r,r.getReplaceRule()). */
\r
211 public void apply(Regex r) { apply(r,r.getReplaceRule()); }
\r
213 /** This finishes the replacement, appending the right() part of
\r
214 the last RegRes given to substitute(RegRes). After this method
\r
215 is called, the Replace object is reset to perform another
\r
216 substitution. If no RegRes objects with a true didMatch are
\r
217 applied, this returns null. */
\r
218 public StringLike finish() {
\r
221 //sb.append(src.substring(pos,src.length()));
\r
222 int s_end = src.length();
\r
223 for(int ii=pos;ii<s_end;ii++)
\r
224 sb.append(src.charAt(ii));
\r
226 lastMatchedTo = pos;
\r
228 StringLike retstr = sb.toStringLike();
\r
232 int lastMatchedTo = 0;
\r
233 public Object clone() {
\r
234 Replacer r = new Replacer();
\r
239 r.lastMatchedTo = lastMatchedTo;
\r
240 r.want_more_text = want_more_text;
\r
241 r.want_more_text_enable = want_more_text_enable;
\r
243 r.rh.prev = rh.prev;
\r
246 public int lastMatchedTo() { return lastMatchedTo; }
\r
247 public Regex getRegex() {
\r
250 public void setSource(StringLike sl) {
\r
253 public void setBuffer(StringBufferLike sbl) {
\r
256 public void setPos(int pos) {
\r