X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fcom%2Fstevesoft%2Fpat%2FReplacer.java;h=062a548eab323e5a985675f7302edc24cfafc1ae;hb=506d60f0e188723ddc91c26824b41ac7034df3fe;hp=c78a11dd8c1cd40a18abbd019002e53831a1a3e8;hpb=c40cf903f740a72ab63dd1abc10fa33450ce660d;p=jalview.git diff --git a/src/com/stevesoft/pat/Replacer.java b/src/com/stevesoft/pat/Replacer.java index c78a11d..062a548 100755 --- a/src/com/stevesoft/pat/Replacer.java +++ b/src/com/stevesoft/pat/Replacer.java @@ -1,261 +1,367 @@ -// -// 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 java.util.*; -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 + * 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 < rmf; ii++) + { + sb.append(src.charAt(ii)); + } + + for (ReplaceRule x = rp; x != null; x = x.next) + { + x.apply(sb, r); + if (x instanceof SpecialRule) + { + if (x instanceof WantMoreTextReplaceRule && want_more_text_enable) + { + want_more_text = true; + } + else if (x instanceof PushRule) + { + RegHolder rh2 = new RegHolder(); + rh2.me = ((PushRule) x).NewRule; + rh2.prev = rh; + rh = rh2; + } + else if (x instanceof PopRule) + { + if (rh.prev != null) + { + rh = rh.prev; + } + } + else if (x instanceof ChangeRule) + { + rh.me = ((ChangeRule) x).NewRule; + } + } + } + if (!want_more_text) + { + pos = r.matchedTo(); + } + } + } + + boolean want_more_text = false, want_more_text_enable = false; + + public boolean WantMoreText() + { + return want_more_text; + } + + /** + * Another form of apply, it is the same as apply(r,r.getReplaceRule()). + */ + public void apply(Regex r) + { + apply(r, r.getReplaceRule()); + } + + /** + * This finishes the replacement, appending the right() part of the last + * RegRes given to substitute(RegRes). After this method is called, the + * Replace object is reset to perform another substitution. If no RegRes + * objects with a true didMatch are applied, this returns null. + */ + public StringLike finish() + { + if (src == null) + { + return null; + } + // sb.append(src.substring(pos,src.length())); + int s_end = src.length(); + for (int ii = pos; ii < s_end; ii++) + { + sb.append(src.charAt(ii)); + } + src = null; + lastMatchedTo = pos; + pos = 0; + StringLike retstr = sb.toStringLike(); + sb = null; + return retstr; + } + + int lastMatchedTo = 0; + + public Object clone() + { + Replacer r = new Replacer(); + r.first = first; + r.src = src; + r.sb = sb; + r.pos = pos; + r.lastMatchedTo = lastMatchedTo; + r.want_more_text = want_more_text; + r.want_more_text_enable = want_more_text_enable; + r.rh.me = rh.me; + r.rh.prev = rh.prev; + return r; + } + + public int lastMatchedTo() + { + return lastMatchedTo; + } + + public Regex getRegex() + { + return rh.me; + } + + public void setSource(StringLike sl) + { + src = sl; + } + + public void setBuffer(StringBufferLike sbl) + { + sb = sbl; + } + + public void setPos(int pos) + { + this.pos = pos; + } +}