// // This software is now distributed according to // the Lesser Gnu Public License. Please see // http://www.gnu.org/copyleft/lesser.txt for // the details. // -- Happy Computing! // package com.stevesoft.pat; import com.stevesoft.pat.wrap.StringWrap; /** Internally used class. */ class RegHolder { Regex me = null; RegHolder prev = null; } /** Internally used class. * @see CodeRule */ class CodeVal { int pos; char code; CodeVal(int p,char c) { pos = p; code = c; } public String toString() { return "("+pos+","+code+")"; } } /** To use this class, first use either the getReplacer() method from Transformer or Regex. You can then use replaceAll, replaceFirst, etc. methods on the Replacer in the same way that you can from either of those two classes.
The only potential difference between using the methods of
Replacer to do the replacing is that Replacer remembers changes
to the replacing object between calls to replaceAll, replaceFirst
etc. For details, see the example file
trans3.java.
@see com.stevesoft.pat.Transformer
@see com.stevesoft.pat.Regex
*/
public class Replacer {
boolean first;
/** Instantiate a new Replacer. */
public Replacer() {}
public StringLike replaceFirstRegion(String s,Regex r,
int start,int end) {
return replaceFirstRegion(new StringWrap(s),r,start,end);
}
/** This method replaces the first occurence of the Regex in the
String starting with position pos
according to the Replacer rule of this object. */
public StringLike replaceFirstRegion(StringLike s,Regex r,
int start,int end) {
first = true;
rh.me = r;
rh.prev = null;
return dorep(s,start,end);
}
public StringLike replaceFirst(StringLike s) {
return replaceFirstRegion(s,0,s.length());
}
public StringLike replaceFirstFrom(StringLike s,int start) {
return replaceFirstRegion(s,start,s.length());
}
public StringLike replaceFirstRegion(StringLike s,int start,int end) {
first = true;
return dorep(s,start,end);
}
RegHolder rh = new RegHolder();
public StringLike replaceAllRegion(String s,Regex r,
int start, int end) {
return replaceAllRegion(new StringWrap(s),r,start,end);
}
/** This method replaces all occurences of the Regex in the
String starting with postition pos
according to the Replacer rule of this object. */
public StringLike replaceAllRegion(StringLike s,Regex r,
int start,int end) {
first = false;
// reset
rh.me = r;
rh.prev = null;
return dorep(s,start,end);
}
public StringLike replaceAll(StringLike s) {
return replaceAllRegion(s,0,s.length());
}
public StringLike replaceAllFrom(StringLike s,int start) {
return replaceAllRegion(s,start,s.length());
}
public StringLike replaceAllRegion(StringLike s,int start,int end) {
first = false;
return dorep(s,start,end);
}
public String replaceAll(String s) {
return replaceAllRegion(new StringWrap(s),0,s.length()).toString();
}
public String replaceAllFrom(String s,int start) {
return replaceAllRegion(new StringWrap(s),start,s.length()).toString();
}
public String replaceAllRegion(String s,int start,int end) {
first = false;
return dorep(new StringWrap(s),start,end).toString();
}
final public boolean isSpecial(ReplaceRule x) {
while(x != null) {
if(x instanceof SpecialRule
|| (x instanceof RuleHolder && ((RuleHolder)x).held instanceof SpecialRule))
return true;
x = x.next;
}
return false;
}
final public void apply1(RegRes rr) {
rr.charsMatched_++;
apply(rr,null);
rr.charsMatched_--;
}
final StringLike dorep(StringLike s,int start,int end) {
StringLike ret = s;
want_more_text = false;
lastMatchedTo = 0;
if(rh.me == null)
throw new NullPointerException("Replacer has null Regex pointer");
if(rh.me._search(s,start,end)) {
int rmn = rh.me.matchedTo();
if(rh.me.charsMatched()==0 && !isSpecial(rh.me.getReplaceRule())) {
apply1(rh.me);
rmn++;
}
apply(rh.me);
if(!first)
for(int i=rmn;
!want_more_text && rh.me._search(s,i,end);i=rmn) {
rmn = rh.me.matchedTo();
if(rh.me.charsMatched()==0) {
if(!isSpecial(rh.me.getReplaceRule()))
apply1(rh.me);
rmn++;
}
apply(rh.me);
}
ret = finish();
ret = ret == null ? s : ret;
}
return ret;
}
StringBufferLike sb = null;
StringLike src = null;
int pos = 0;
/** This method allows you to apply the results of several
matches in a sequence to modify a String of text. Each
call in the sequence must operate on the same piece of
text and the matchedFrom() of each RegRes given to this
method must be greater in value than the preceeding
RegRes's matchedTo() value.
*/
public void apply(RegRes r,ReplaceRule rp) {
if(rp==null ||(rp.next == null && rp instanceof AmpersandRule))
return;
if(r.didMatch()) {
if(src == null)
src = r.getStringLike();
if(sb == null)
sb = new StringBufferLike(src.newStringBufferLike());
int rmf = r.matchedFrom();
for(int ii=pos;ii