-//\r
-// This software is now distributed according to\r
-// the Lesser Gnu Public License. Please see\r
-// http://www.gnu.org/copyleft/lesser.txt for\r
-// the details.\r
-// -- Happy Computing!\r
-//\r
-package com.stevesoft.pat;\r
-\r
-import com.stevesoft.pat.wrap.*;\r
-\r
-/** Internally used class. */\r
-class RegHolder\r
-{\r
- Regex me = null;\r
- RegHolder prev = null;\r
-}\r
-\r
-/** Internally used class.\r
- * @see CodeRule\r
- */\r
-class CodeVal\r
-{\r
- int pos;\r
- char code;\r
- CodeVal(int p, char c)\r
- {\r
- pos = p;\r
- code = c;\r
- }\r
-\r
- public String toString()\r
- {\r
- return "(" + pos + "," + code + ")";\r
- }\r
-}\r
-\r
-/**\r
- To use this class, first use either the getReplacer() method from\r
- Transformer or Regex. You can then use replaceAll, replaceFirst,\r
- etc. methods on the Replacer in the same way that you can from\r
- either of those two classes.\r
- <p>\r
- The only potential difference between using the methods of\r
- Replacer to do the replacing is that Replacer remembers changes\r
- to the replacing object between calls to replaceAll, replaceFirst\r
- etc. For details, see the example file\r
- <a href="http://javaregex.com/code/trans3.java.html">trans3.java</a>.\r
- @see com.stevesoft.pat.Transformer\r
- @see com.stevesoft.pat.Regex\r
- */\r
-public class Replacer\r
-{\r
- boolean first;\r
-\r
- /** Instantiate a new Replacer. */\r
- public Replacer()\r
- {}\r
-\r
- public StringLike replaceFirstRegion(String s, Regex r,\r
- int start, int end)\r
- {\r
- return replaceFirstRegion(new StringWrap(s), r, start, end);\r
- }\r
-\r
- /** This method replaces the first occurence of the Regex in the\r
- String starting with position pos\r
- according to the Replacer rule of this object. */\r
- public StringLike replaceFirstRegion(StringLike s, Regex r,\r
- int start, int end)\r
- {\r
- first = true;\r
- rh.me = r;\r
- rh.prev = null;\r
- return dorep(s, start, end);\r
- }\r
-\r
- public StringLike replaceFirst(StringLike s)\r
- {\r
- return replaceFirstRegion(s, 0, s.length());\r
- }\r
-\r
- public StringLike replaceFirstFrom(StringLike s, int start)\r
- {\r
- return replaceFirstRegion(s, start, s.length());\r
- }\r
-\r
- public StringLike replaceFirstRegion(StringLike s, int start, int end)\r
- {\r
- first = true;\r
- return dorep(s, start, end);\r
- }\r
-\r
- RegHolder rh = new RegHolder();\r
-\r
- public StringLike replaceAllRegion(String s, Regex r,\r
- int start, int end)\r
- {\r
- return replaceAllRegion(new StringWrap(s), r, start, end);\r
- }\r
-\r
- /** This method replaces all occurences of the Regex in the\r
- String starting with postition pos\r
- according to the Replacer rule of this object. */\r
- public StringLike replaceAllRegion(StringLike s, Regex r,\r
- int start, int end)\r
- {\r
- first = false;\r
- // reset\r
- rh.me = r;\r
- rh.prev = null;\r
- return dorep(s, start, end);\r
- }\r
-\r
- public StringLike replaceAll(StringLike s)\r
- {\r
- return replaceAllRegion(s, 0, s.length());\r
- }\r
-\r
- public StringLike replaceAllFrom(StringLike s, int start)\r
- {\r
- return replaceAllRegion(s, start, s.length());\r
- }\r
-\r
- public StringLike replaceAllRegion(StringLike s, int start, int end)\r
- {\r
- first = false;\r
- return dorep(s, start, end);\r
- }\r
-\r
- public String replaceAll(String s)\r
- {\r
- return replaceAllRegion(new StringWrap(s), 0, s.length()).toString();\r
- }\r
-\r
- public String replaceAllFrom(String s, int start)\r
- {\r
- return replaceAllRegion(new StringWrap(s), start, s.length()).toString();\r
- }\r
-\r
- public String replaceAllRegion(String s, int start, int end)\r
- {\r
- first = false;\r
- return dorep(new StringWrap(s), start, end).toString();\r
- }\r
-\r
- final public boolean isSpecial(ReplaceRule x)\r
- {\r
- while (x != null)\r
- {\r
- if (x instanceof SpecialRule\r
- ||\r
- (x instanceof RuleHolder && ( (RuleHolder) x).held instanceof SpecialRule))\r
- {\r
- return true;\r
- }\r
- x = x.next;\r
- }\r
- return false;\r
- }\r
-\r
- final public void apply1(RegRes rr)\r
- {\r
- rr.charsMatched_++;\r
- apply(rr, null);\r
- rr.charsMatched_--;\r
- }\r
-\r
- final StringLike dorep(StringLike s, int start, int end)\r
- {\r
- StringLike ret = s;\r
- want_more_text = false;\r
- lastMatchedTo = 0;\r
- if (rh.me == null)\r
- {\r
- throw new NullPointerException("Replacer has null Regex pointer");\r
- }\r
- if (rh.me._search(s, start, end))\r
- {\r
- int rmn = rh.me.matchedTo();\r
- if (rh.me.charsMatched() == 0 && !isSpecial(rh.me.getReplaceRule()))\r
- {\r
- apply1(rh.me);\r
- rmn++;\r
- }\r
- apply(rh.me);\r
- if (!first)\r
- {\r
- for (int i = rmn;\r
- !want_more_text && rh.me._search(s, i, end); i = rmn)\r
- {\r
- rmn = rh.me.matchedTo();\r
- if (rh.me.charsMatched() == 0)\r
- {\r
- if (!isSpecial(rh.me.getReplaceRule()))\r
- {\r
- apply1(rh.me);\r
- }\r
- rmn++;\r
- }\r
- apply(rh.me);\r
- }\r
- }\r
- ret = finish();\r
- ret = ret == null ? s : ret;\r
- }\r
- return ret;\r
- }\r
-\r
- StringBufferLike sb = null;\r
- StringLike src = null;\r
- int pos = 0;\r
- /** This method allows you to apply the results of several\r
- matches in a sequence to modify a String of text. Each\r
- call in the sequence must operate on the same piece of\r
- text and the matchedFrom() of each RegRes given to this\r
- method must be greater in value than the preceeding\r
- RegRes's matchedTo() value.\r
- */\r
- public void apply(RegRes r, ReplaceRule rp)\r
- {\r
- if (rp == null || (rp.next == null && rp instanceof AmpersandRule))\r
- {\r
- return;\r
- }\r
- if (r.didMatch())\r
- {\r
- if (src == null)\r
- {\r
- src = r.getStringLike();\r
- }\r
- if (sb == null)\r
- {\r
- sb = new StringBufferLike(src.newStringBufferLike());\r
- }\r
- int rmf = r.matchedFrom();\r
- for (int ii = pos; ii < rmf; ii++)\r
- {\r
- sb.append(src.charAt(ii));\r
- }\r
-\r
- for (ReplaceRule x = rp; x != null; x = x.next)\r
- {\r
- x.apply(sb, r);\r
- if (x instanceof SpecialRule)\r
- {\r
- if (x instanceof WantMoreTextReplaceRule\r
- && want_more_text_enable)\r
- {\r
- want_more_text = true;\r
- }\r
- else if (x instanceof PushRule)\r
- {\r
- RegHolder rh2 = new RegHolder();\r
- rh2.me = ( (PushRule) x).NewRule;\r
- rh2.prev = rh;\r
- rh = rh2;\r
- }\r
- else if (x instanceof PopRule)\r
- {\r
- if (rh.prev != null)\r
- {\r
- rh = rh.prev;\r
- }\r
- }\r
- else if (x instanceof ChangeRule)\r
- {\r
- rh.me = ( (ChangeRule) x).NewRule;\r
- }\r
- }\r
- }\r
- if (!want_more_text)\r
- {\r
- pos = r.matchedTo();\r
- }\r
- }\r
- }\r
-\r
- boolean want_more_text = false, want_more_text_enable = false;\r
- public boolean WantMoreText()\r
- {\r
- return want_more_text;\r
- }\r
-\r
- /** Another form of apply, it is the same as\r
- apply(r,r.getReplaceRule()). */\r
- public void apply(Regex r)\r
- {\r
- apply(r, r.getReplaceRule());\r
- }\r
-\r
- /** This finishes the replacement, appending the right() part of\r
- the last RegRes given to substitute(RegRes). After this method\r
- is called, the Replace object is reset to perform another\r
- substitution. If no RegRes objects with a true didMatch are\r
- applied, this returns null. */\r
- public StringLike finish()\r
- {\r
- if (src == null)\r
- {\r
- return null;\r
- }\r
- //sb.append(src.substring(pos,src.length()));\r
- int s_end = src.length();\r
- for (int ii = pos; ii < s_end; ii++)\r
- {\r
- sb.append(src.charAt(ii));\r
- }\r
- src = null;\r
- lastMatchedTo = pos;\r
- pos = 0;\r
- StringLike retstr = sb.toStringLike();\r
- sb = null;\r
- return retstr;\r
- }\r
-\r
- int lastMatchedTo = 0;\r
- public Object clone()\r
- {\r
- Replacer r = new Replacer();\r
- r.first = first;\r
- r.src = src;\r
- r.sb = sb;\r
- r.pos = pos;\r
- r.lastMatchedTo = lastMatchedTo;\r
- r.want_more_text = want_more_text;\r
- r.want_more_text_enable = want_more_text_enable;\r
- r.rh.me = rh.me;\r
- r.rh.prev = rh.prev;\r
- return r;\r
- }\r
-\r
- public int lastMatchedTo()\r
- {\r
- return lastMatchedTo;\r
- }\r
-\r
- public Regex getRegex()\r
- {\r
- return rh.me;\r
- }\r
-\r
- public void setSource(StringLike sl)\r
- {\r
- src = sl;\r
- }\r
-\r
- public void setBuffer(StringBufferLike sbl)\r
- {\r
- sb = sbl;\r
- }\r
-\r
- public void setPos(int pos)\r
- {\r
- this.pos = pos;\r
- }\r
-}\r
+//
+// 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 jalview.util.MessageManager;
+
+import com.stevesoft.pat.wrap.*;
+
+/** 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.
+ * <p>
+ * 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 <a
+ * href="http://javaregex.com/code/trans3.java.html">trans3.java</a>.
+ *
+ * @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(MessageManager.getString("exception.replace_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;
+ }
+}