2 // This software is now distributed according to
3 // the Lesser Gnu Public License. Please see
4 // http://www.gnu.org/copyleft/lesser.txt for
8 package com.stevesoft.pat;
10 import java.util.Hashtable;
13 * ReplaceRule is a singly linked list of Objects which describe how to replace
14 * the matched portion of a String. The only member method that you absolutely
15 * need to define to use this class is apply(StringBuffer,RegRes) -- although
16 * you may want define toString1() and clone1() (if you are unhappy with the
17 * default methods) that are needed by the clone() or toString() methods on this
18 * class. During the replacement process, each ReplaceRule tells the replacer
19 * what to add to javajs.util.SB and uses the contents of the Regular expression
20 * result to get the information it needs to do this. Here is an <a
21 * href="http://javaregex.com/code/fancy.java.html">example</a>
23 * @see com.stevesoft.pat.NullRule
24 * @see com.stevesoft.pat.AmpersandRule
25 * @see com.stevesoft.pat.BackRefRule
26 * @see com.stevesoft.pat.LeftRule
27 * @see com.stevesoft.pat.RightRule
28 * @see com.stevesoft.pat.StringRule
30 public abstract class ReplaceRule
32 /** points to the next ReplaceRule in the linked list. */
33 protected ReplaceRule next = null;
36 * This function appends to the StringBufferLike the text you want to replaced
37 * the portion of the String last matched.
39 public abstract void apply(StringBufferLike sb, RegRes r);
42 * A rule describing how to clone only the current ReplaceRule, and none of
43 * the others in this linked list. It is called by clone() for each item in
46 public Object clone1()
48 return new RuleHolder(this);
51 public final Object clone()
53 ReplaceRule x = (ReplaceRule) clone1();
56 while (y.next != null)
58 x.next = (ReplaceRule) y.next.clone1();
66 static ReplaceRule add(ReplaceRule head, ReplaceRule adding)
76 public ReplaceRule add(ReplaceRule adding)
78 return add(this, adding);
81 /** Add another ReplaceRule to the linked list. */
82 public void addRule(ReplaceRule r)
94 static Regex getvar = null;
96 final static Regex getv()
98 // Thanks to Michael Jimenez for pointing out the need
99 // to clone getvar rather than simply returning it.
100 // Previously this was not thread safe.
101 // if(getvar != null) return getvar;
104 return (Regex) getvar.clone();
106 getvar = new Regex("(?:\\\\(\\d+)|" + // ref 1
107 "\\$(?:" + "(\\d+)|" + // ref 2
109 "([&'`])|" + // ref 4
110 "\\{(?:(\\d+)|" + // ref 5
111 "([^\n}\\\\]+))}" + // ref 6
112 ")|" + "\\\\([nrbtaef])|" + // ref 7
113 "\\\\c([\u0000-\uFFFF])|" + // ref 8
114 "\\\\x([A-Fa-f0-9]{2})|" + // ref 9
115 "\\\\([\u0000-\uFFFF])" + // ref 10
121 static Hashtable defs = new Hashtable();
123 public static boolean isDefined(String s)
125 return defs.get(s) != null;
128 public static void define(String s, Regex r)
133 public static void define(String s, ReplaceRule r)
139 String name = getClass().getName();
141 public static void define(String s, Transformer t)
146 public static void undefine(String s)
152 * This tells how to convert just the current element (and none of the other
153 * items in the linked list) to a String. This method is called by toString()
154 * for each item in the linked list.
156 public String toString1()
158 return "${" + name + "}";
161 /** Convert to a String. */
162 public final String toString()
164 javajs.util.SB sb = new javajs.util.SB();
165 sb.append(toString1());
166 ReplaceRule rr = this.next;
169 sb.append(rr.toString1());
172 return sb.toString();
176 * Modified the behavior of a ReplaceRule by supplying an argument. If a
177 * ReplaceRule named "foo" is defined and the pattern "s/x/${foo:5}/" is given
178 * to Regex.perlCode, then the "foo" the definition of "foo" will be retrieved
179 * and arg("5") will be called. If the result is non-null, that is the
180 * ReplaceRule that will be used. If the result is null, then the pattern
181 * works just as if it were "s/x/${foo}/".
183 * @see com.stevesoft.pat.Validator#arg(java.lang.String)
185 public ReplaceRule arg(String s)
190 static int getHexDigit(char c)
192 if (c >= '0' && c <= '9')
196 if (c >= 'a' && c <= 'f')