X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fcom%2Fstevesoft%2Fpat%2FTransformer.java;h=901a92d1bb78ca1f2dfd2d37183efb583ee1a5a5;hb=236b7a125d995a097de4ee42d022320f382e7027;hp=14f7e38457def26a6079354e7bb3caa0a022d05b;hpb=f24dacb1da56fccf05d684e2f4899facec2aecf7;p=jalview.git diff --git a/src/com/stevesoft/pat/Transformer.java b/src/com/stevesoft/pat/Transformer.java index 14f7e38..901a92d 100755 --- a/src/com/stevesoft/pat/Transformer.java +++ b/src/com/stevesoft/pat/Transformer.java @@ -1,154 +1,237 @@ -// -// 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; - -/** Replacement rule used by the Transformer. - @see com.stevesoft.pat.Transformer - */ -class TransRepRule extends ReplaceRule { - Transformer t; - TransRepRule(Transformer t) { this.t = t; } - public String toString1() { return ""; } - public Object clone1() { return new TransRepRule(t); } - public void apply(StringBufferLike sb,RegRes rr) { - // get the ReplaceRule of the Regex that matched. - next = t.tp.ra[t.tp.pn].getReplaceRule(); - } -} - -/** Sometimes you want to replace a whole bunch of things - that might occur within a single line of text. One efficient - way to do this, both in terms of performance and programming - ease, is with Transformer. The Transformer contains an array - of Regex's and uses the Regex that matches earliest within the - text to do the replacing, if two Regex's match at the same - time it uses the one put in the Transformer first. -

- This feature can be used to prevent transformations from - occurring in certain regions. For example, if I add the rule - s'//.*'$&' and then add the - rule s/hello/goodbye/ the Transformer will replace "hello" - with "goodbye" except when it occurs inside a double-slash - style of comment. The transformation on the comment goes first, - does nothing, and precludes transformation on the same region - of text as the s/hello/goodbye/ rule. -

- So far, at least, this class does not have the capability of - turning into a giant robot :-) - */ -public class Transformer { - TransPat tp; - Regex rp = new Regex(); - boolean auto_optimize; - - /** Get a replacer to that works with the current Regex. - @see com.stevesoft.pat.Replacer - */ - public Replacer getReplacer() { return rp.getReplacer(); } - - /** Instantiate a new Transformer object. */ - public Transformer(boolean auto) { - auto_optimize = auto; - tp = new TransPat(); - rp.setReplaceRule(new TransRepRule(this)); - rp.thePattern = tp; - } - - /** Add a new Regex to the set of Regex's. */ - public void add(Regex r) { - if(auto_optimize) r.optimize(); - tp.ra[tp.ra_len++] = r; - if(tp.ra.length==tp.ra_len) { - Regex[] ra2 = new Regex[tp.ra_len+10]; - for(int i=0;i rp.numSubs_ ? r.numSubs_ : rp.numSubs_; - } - - /** Returns the number of Regex's in this Transformer. */ - public int patterns() { return tp.ra_len; } - - /** Get the Regex at position i in this Transformer. */ - public Regex getRegexAt(int i) { - if(i >= tp.ra_len) - throw new ArrayIndexOutOfBoundsException("i="+i+">="+patterns()); - if(i < 0) - throw new ArrayIndexOutOfBoundsException("i="+i+"< 0"); - return tp.ra[i]; - } - /** Set the Regex at position i in this Transformer. */ - public void setRegexAt(Regex rx,int i) { - if(i >= tp.ra_len) - throw new ArrayIndexOutOfBoundsException("i="+i+">="+patterns()); - if(i < 0) - throw new ArrayIndexOutOfBoundsException("i="+i+"< 0"); - tp.ra[i] = rx; - } - - /** Add a new Regex by calling Regex.perlCode - @see com.stevesoft.pat.Regex#perlCode(java.lang.String) - */ - public void add(String rs) { - Regex r = Regex.perlCode(rs); - if(r == null) throw new NullPointerException("bad pattern to Regex.perlCode: "+rs); - add(r); - } - /** Add an array of Strings (which will be converted to - Regex's via the Regex.perlCode method. - @see com.stevesoft.pat.Regex#perlCode(java.lang.String) - */ - public void add(String[] array) { - for(int i=0;i + * This feature can be used to prevent transformations from occurring in certain + * regions. For example, if I add the rule s'//.*'$&' and then add the rule + * s/hello/goodbye/ the Transformer will replace "hello" with "goodbye" except + * when it occurs inside a double-slash style of comment. The transformation on + * the comment goes first, does nothing, and precludes transformation on the + * same region of text as the s/hello/goodbye/ rule. + *

+ * So far, at least, this class does not have the capability of turning into a + * giant robot :-) + */ +public class Transformer +{ + TransPat tp; + + Regex rp = new Regex(); + + boolean auto_optimize; + + /** + * Get a replacer to that works with the current Regex. + * + * @see com.stevesoft.pat.Replacer + */ + public Replacer getReplacer() + { + return rp.getReplacer(); + } + + /** Instantiate a new Transformer object. */ + public Transformer(boolean auto) + { + auto_optimize = auto; + tp = new TransPat(); + rp.setReplaceRule(new TransRepRule(this)); + rp.thePattern = tp; + } + + /** Add a new Regex to the set of Regex's. */ + public void add(Regex r) + { + if (auto_optimize) + { + r.optimize(); + } + tp.ra[tp.ra_len++] = r; + if (tp.ra.length == tp.ra_len) + { + Regex[] ra2 = new Regex[tp.ra_len + 10]; + for (int i = 0; i < tp.ra_len; i++) + { + ra2[i] = tp.ra[i]; + } + tp.ra = ra2; + } + rp.numSubs_ = r.numSubs_ > rp.numSubs_ ? r.numSubs_ : rp.numSubs_; + } + + /** Returns the number of Regex's in this Transformer. */ + public int patterns() + { + return tp.ra_len; + } + + /** Get the Regex at position i in this Transformer. */ + public Regex getRegexAt(int i) + { + if (i >= tp.ra_len) + { + throw new ArrayIndexOutOfBoundsException("i=" + i + ">=" + patterns()); + } + if (i < 0) + { + throw new ArrayIndexOutOfBoundsException("i=" + i + "< 0"); + } + return tp.ra[i]; + } + + /** Set the Regex at position i in this Transformer. */ + public void setRegexAt(Regex rx, int i) + { + if (i >= tp.ra_len) + { + throw new ArrayIndexOutOfBoundsException("i=" + i + ">=" + patterns()); + } + if (i < 0) + { + throw new ArrayIndexOutOfBoundsException("i=" + i + "< 0"); + } + tp.ra[i] = rx; + } + + /** + * Add a new Regex by calling Regex.perlCode + * + * @see com.stevesoft.pat.Regex#perlCode(java.lang.String) + */ + public void add(String rs) + { + Regex r = Regex.perlCode(rs); + if (r == null) + { + throw new NullPointerException(MessageManager.formatMessage( + "exception.bad_pattern_to_regex_perl_code", + new String[] { rs })); + } + add(r); + } + + /** + * Add an array of Strings (which will be converted to Regex's via the + * Regex.perlCode method. + * + * @see com.stevesoft.pat.Regex#perlCode(java.lang.String) + */ + public void add(String[] array) + { + for (int i = 0; i < array.length; i++) + { + add(array[i]); + } + } + + /** Replace all matches in the current String. */ + public String replaceAll(String s) + { + return dorep(s, 0, s.length()); + } + + public StringLike replaceAll(StringLike s) + { + return dorep(s, 0, s.length()); + } + + /** Replace all matching patterns beginning at position start. */ + public String replaceAllFrom(String s, int start) + { + return dorep(s, start, s.length()); + } + + /** + * Replace all matching patterns beginning between the positions start and end + * inclusive. + */ + public String replaceAllRegion(String s, int start, int end) + { + return dorep(s, start, end); + } + + Replacer repr = new Replacer(); + + final StringLike dorep(StringLike s, int start, int end) + { + StringLike tfmd = repr.replaceAllRegion(s, rp, start, end); + tp.lastMatchedTo = repr.lastMatchedTo; + return tfmd; + } + + final String dorep(String s, int start, int end) + { + return dorep(new StringWrap(s), start, end).toString(); + } + + /** Replace the first matching pattern in String s. */ + public String replaceFirst(String s) + { + return dorep(s, 0, s.length()); + } + + /** + * Replace the first matching pattern after position start in String s. + */ + public String replaceFirstFrom(String s, int start) + { + return dorep(s, start, s.length()); + } + + /** + * Replace the first matching pattern that begins between start and end + * inclusive. + */ + public String replaceFirstRegion(String s, int start, int end) + { + return dorep(s, start, end); + } +}