package com.github.xbn.regexutil; import java.util.regex.*; /** <p>The inspiration for {@code RegexReplacer}, by Elliott Hughes and Roger Millington. A rewriter does a global regex substitution in the strings passed to its 'rewrite' method.</p> <p>This class was downloaded from (11/28/2010) <br/>     <code><a href="http://elliotth.blogspot.com/2004/07/java-implementation-of-rubys-gsub.html">http://elliotth.blogspot.com/2004/07/java-implementation-of-rubys-gsub.html</a></code></p> <p><ul> <li>Example: {@code java com.github.xbn.regexutil.Rewriter}</li> </ul></p> <p>It uses the pattern supplied to its constructor, and is like 'String.replaceAll' except for the fact that its replacement strings are generated by invoking a method you write, rather than from another string.</p> <p>This class is supposed to be equivalent to Ruby's 'gsub' when given a block. This is the nicest syntax I've managed to come up with in Java so far. It's not too bad, and might actually be preferable if you want to do the same rewriting to a number of strings in the same method or class.</p> * @author Elliott Hughes * @author Roger Millington */ public abstract class Rewriter { private Pattern pattern; private Matcher matcher; /** * Constructs a rewriter using the given regular expression; * the syntax is the same as for 'Pattern.compile'. */ public Rewriter(String regularExpression) { this.pattern = Pattern.compile(regularExpression); } /** * Returns the input subsequence captured by the given group * during the previous match operation. */ public String group(int i) { return matcher.group(i); } /** * Overridden to compute a replacement for each match. Use * the method 'group' to access the captured groups. */ public abstract String replacement(); /** * Returns the result of rewriting 'original' by invoking the method 'replacement' for each match of the regular expression supplied to the constructor. */ public String rewrite(CharSequence original) { return rewrite(original, new StringBuffer(original.length())).toString(); } /** * Returns the result of appending the rewritten 'original' to 'destination'. * We have to use StringBuffer rather than the more obvious and general Appendable because of Matcher's interface (Sun bug 5066679). * Most users will prefer the single-argument rewrite, which supplies a temporary StringBuffer itself. */ public StringBuffer rewrite(CharSequence original, StringBuffer destination) { this.matcher = pattern.matcher(original); while (matcher.find()) { matcher.appendReplacement(destination, ""); destination.append(replacement()); } matcher.appendTail(destination); return destination; } public static void main(String[] arguments) { // Rewrite an ancient unit of length in SI units. String result = new Rewriter("([0-9]+(\\.[0-9]+)?)[- ]?(inch(es)?)") { public String replacement() { float inches = Float.parseFloat(group(1)); return Float.toString(2.54f * inches) + " cm"; } }.rewrite("a 17 inch display"); System.out.println(result); // The "Searching and Replacing with Non-Constant Values Using a // Regular Expression" example from the Java Almanac. result = new Rewriter("([a-zA-Z]+[0-9]+)") { public String replacement() { return group(1).toUpperCase(); } }.rewrite("ab12 cd efg34"); System.out.println(result); result = new Rewriter("([0-9]+) US cents") { public String replacement() { long dollars = Long.parseLong(group(1))/100; return "$" + dollars; } }.rewrite("5000 US cents"); System.out.println(result); /* //Requires e.util.TimeUtilities: // Rewrite durations in milliseconds in ISO 8601 format. Rewriter rewriter = new Rewriter("(\\d+)\\s*ms") { public String replacement() { long milliseconds = Long.parseLong(group(1)); return TimeUtilities.msToIsoString(milliseconds); } }; result = rewriter.rewrite("232341243 ms"); System.out.println(result); for (String argument : arguments) { System.out.println(rewriter.rewrite(argument)); } */ } }