package be.jeffcheasey88.peeratcode.parser.java; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.function.Function; import java.util.regex.Matcher; import java.util.regex.Pattern; public class CleanerPool{ private List cleaners; public CleanerPool(Cleaner... cleaners){ this.cleaners = Arrays.asList(cleaners); } public String clean(String value){ for(Cleaner cleaner : this.cleaners) value = cleaner.clean(value); return value; } public String unzip(String value){ return unzip(value, (s) -> s); } public String unzip(String value, Function modifier){ boolean edited = false; for(Cleaner cleaner : this.cleaners){ Matcher matcher = cleaner.getMatcher(value); if(matcher.matches()){ String key = matcher.group(2); String zip = cleaner.getConstant(key); value = matcher.group(1)+cleaner.open+modifier.apply(zip)+cleaner.close+matcher.group(3); edited = true; } } if(edited) return unzip(value, modifier); return value; } public static class Cleaner{ private Pattern rPattern; private String pattern; private char open; private char close; public List constants; public Cleaner(String pattern, char open, char close){ this.pattern = "$"+pattern; this.open = open; this.close = close; this.rPattern = Pattern.compile("^(.*)(\\$"+pattern+"\\d+)(.*)$"); this.constants = new ArrayList<>(); } public Matcher getMatcher(String value){ return this.rPattern.matcher(value); } public String getPattern(){ return this.pattern; } public String getConstant(String value){ return this.constants.get(Integer.parseInt(value.replace(this.pattern, ""))); } public String clean(String value){ StringBuilder builder = new StringBuilder(); for(int i = 0; i < value.length(); i++){ char c = value.charAt(i); if(c == open){ i+=cutOpenable(value.substring(i+1), constants, pattern, open, close); builder.append(pattern+(constants.size()-1)); }else{ builder.append(c); } } return builder.toString(); } private int cutOpenable(String value, List constants, String pattern, char open, char close){ StringBuilder builder = new StringBuilder(); int i = 0; for(;i < value.length(); i++){ char c = value.charAt(i); if(c == close){ break; }else if(c == open){ i+=cutOpenable(value.substring(i+1), constants, pattern, open, close); builder.append(pattern+(constants.size()-1)); }else{ builder.append(c); } } constants.add(builder.toString()); return i+1; } } }