com.groupbyinc.common.jregex.Replacer Maven / Gradle / Ivy
The newest version!
/**
* Copyright (c) 2001, Sergey A. Samokhodkin
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form
* must reproduce the above copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided with the distribution.
* - Neither the name of jregex nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* @version 1.2_01
*/
package jregex;
import java.io.*;
import java.util.Hashtable;
/**
* The Replacer class suggests some methods to replace occurences of a pattern
* either by a result of evaluation of a perl-like expression, or by a plain string,
* or according to a custom substitution model, provided as a Substitution interface implementation.
* A Replacer instance may be obtained either using Pattern.replacer(...) method, or by constructor:
* Pattern p=new Pattern("\\w+");
* Replacer perlExpressionReplacer=p.replacer("[$&]");
* //or another way to do the same
* Substitution myOwnModel=new Substitution(){
* public void appendSubstitution(MatchResult match,TextBuffer tb){
* tb.append('[');
* match.getGroup(MatchResult.MATCH,tb);
* tb.append(']');
* }
* }
* Replacer myVeryOwnReplacer=new Replacer(p,myOwnModel);
*
* The second method is much more verbose, but gives more freedom.
* To perform a replacement call replace(someInput):
* System.out.print(perlExpressionReplacer.replace("All your base "));
* System.out.println(myVeryOwnReplacer.replace("are belong to us"));
* //result: "[All] [your] [base] [are] [belong] [to] [us]"
*
* @see Substitution
* @see PerlSubstitution
* @see Replacer#Replacer(jregex.Pattern,jregex.Substitution)
*/
public class Replacer{
private Pattern pattern;
private Substitution substitution;
/**
*/
public Replacer(Pattern pattern,Substitution substitution){
this.pattern=pattern;
this.substitution=substitution;
}
/**
*/
public Replacer(Pattern pattern, String substitution){
this(pattern,substitution,true);
}
/**
*/
public Replacer(Pattern pattern, String substitution, boolean isPerlExpr){
this.pattern=pattern;
this.substitution= isPerlExpr? (Substitution)new PerlSubstitution(substitution):
new DummySubstitution(substitution);
}
public void setSubstitution(String s, boolean isPerlExpr){
substitution= isPerlExpr? (Substitution)new PerlSubstitution(s):
new DummySubstitution(s);
}
/**
*/
public String replace(String text){
TextBuffer tb=wrap(new StringBuffer(text.length()));
replace(pattern.matcher(text),substitution,tb);
return tb.toString();
}
/**
*/
public String replace(char[] chars,int off,int len){
TextBuffer tb=wrap(new StringBuffer(len));
replace(pattern.matcher(chars,off,len),substitution,tb);
return tb.toString();
}
/**
*/
public String replace(MatchResult res,int group){
TextBuffer tb=wrap(new StringBuffer());
replace(pattern.matcher(res,group),substitution,tb);
return tb.toString();
}
/**
*/
public String replace(Reader text,int length)throws IOException{
TextBuffer tb=wrap(new StringBuffer(length>=0? length: 0));
replace(pattern.matcher(text,length),substitution,tb);
return tb.toString();
}
/**
*/
public int replace(String text,StringBuffer sb){
return replace(pattern.matcher(text),substitution,wrap(sb));
}
/**
*/
public int replace(char[] chars,int off,int len,StringBuffer sb){
return replace(chars,off,len,wrap(sb));
}
/**
*/
public int replace(MatchResult res,int group,StringBuffer sb){
return replace(res,group,wrap(sb));
}
/**
*/
public int replace(MatchResult res,String groupName,StringBuffer sb){
return replace(res,groupName,wrap(sb));
}
public int replace(Reader text,int length,StringBuffer sb)throws IOException{
return replace(text,length,wrap(sb));
}
/**
*/
public int replace(String text,TextBuffer dest){
return replace(pattern.matcher(text),substitution,dest);
}
/**
*/
public int replace(char[] chars,int off,int len,TextBuffer dest){
return replace(pattern.matcher(chars,off,len),substitution,dest);
}
/**
*/
public int replace(MatchResult res,int group,TextBuffer dest){
return replace(pattern.matcher(res,group),substitution,dest);
}
/**
*/
public int replace(MatchResult res,String groupName,TextBuffer dest){
return replace(pattern.matcher(res,groupName),substitution,dest);
}
public int replace(Reader text,int length,TextBuffer dest)throws IOException{
return replace(pattern.matcher(text,length),substitution,dest);
}
/**
* Replaces all occurences of a matcher's pattern in a matcher's target
* by a given substitution appending the result to a buffer.
* The substitution starts from current matcher's position, current match
* not included.
*/
public static int replace(Matcher m,Substitution substitution,TextBuffer dest){
boolean firstPass=true;
int c=0;
while(m.find()){
if(m.end()==0 && !firstPass) continue; //allow to replace at "^"
if(m.start()>0) m.getGroup(MatchResult.PREFIX,dest);
substitution.appendSubstitution(m,dest);
c++;
m.setTarget(m,MatchResult.SUFFIX);
firstPass=false;
}
m.getGroup(MatchResult.TARGET,dest);
return c;
}
public static int replace(Matcher m,Substitution substitution,Writer out) throws IOException{
try{
return replace(m,substitution,wrap(out));
}
catch(WriteException e){
throw e.reason;
}
}
/**
*/
public void replace(String text,Writer out) throws IOException{
replace(pattern.matcher(text),substitution,out);
}
/**
*/
public void replace(char[] chars,int off,int len,Writer out) throws IOException{
replace(pattern.matcher(chars,off,len),substitution,out);
}
/**
*/
public void replace(MatchResult res,int group,Writer out) throws IOException{
replace(pattern.matcher(res,group),substitution,out);
}
/**
*/
public void replace(MatchResult res,String groupName,Writer out) throws IOException{
replace(pattern.matcher(res,groupName),substitution,out);
}
public void replace(Reader in,int length,Writer out)throws IOException{
replace(pattern.matcher(in,length),substitution,out);
}
private static class DummySubstitution implements Substitution{
String str;
DummySubstitution(String s){
str=s;
}
public void appendSubstitution(MatchResult match,TextBuffer res){
if(str!=null) res.append(str);
}
}
public static TextBuffer wrap(final StringBuffer sb){
return new TextBuffer(){
public void append(char c){
sb.append(c);
}
public void append(char[] chars,int start,int len){
sb.append(chars,start,len);
}
public void append(String s){
sb.append(s);
}
public String toString(){
return sb.toString();
}
};
}
public static TextBuffer wrap(final Writer writer){
return new TextBuffer(){
public void append(char c){
try{
writer.write(c);
}
catch(IOException e){
throw new WriteException(e);
}
}
public void append(char[] chars,int off,int len){
try{
writer.write(chars,off,len);
}
catch(IOException e){
throw new WriteException(e);
}
}
public void append(String s){
try{
writer.write(s);
}
catch(IOException e){
throw new WriteException(e);
}
}
};
}
private static class WriteException extends RuntimeException{
IOException reason;
WriteException(IOException io){
reason=io;
}
}
}