static final Regex getv() { // Thanks to Michael Jimenez for pointing out the need // to clone getvar rather than simply returning it. // Previously this was not thread safe. // if(getvar != null) return getvar; if (getvar != null) return (Regex) getvar.clone(); getvar = new Regex( "(?:\\\\(\\d+)|" + // ref 1 "\\$(?:" + "(\\d+)|" + // ref 2 "(\\w+)|" + // ref 3 "([&'`])|" + // ref 4 "\\{(?:(\\d+)|" + // ref 5 "([^\n}\\\\]+))}" + // ref 6 ")|" + "\\\\([nrbtaef])|" + // ref 7 "\\\\c([\u0000-\uFFFF])|" + // ref 8 "\\\\x([A-Fa-f0-9]{2})|" + // ref 9 "\\\\([\u0000-\uFFFF])" + // ref 10 ")"); getvar.optimize(); return getvar; }
@Override public void meet(Regex re) throws RuntimeException { builder.append( optimizeRegexp( new ValueExpressionEvaluator(re.getArg(), parent, ValueType.STRING).build(), new ValueExpressionEvaluator(re.getPatternArg(), parent, ValueType.STRING).build(), re.getFlagsArg())); }
/** * Compile a ReplaceRule using the text that would go between the second and third /'s in a * typical substitution pattern in Perl: s/ ... / <i>The argument to ReplaceRule.perlCode</i> /. */ public static ReplaceRule perlCode(String s) { // String sav_backGs = Regex.backGs; // int sav_backGto = Regex.backGto; try { int mf = 0, mt = 0; Regex gv = getv(); ReplaceRule head = null; Object tmp = null; while (gv.searchFrom(s, mt)) { int off = Regex.BackRefOffset - 1; mf = gv.matchedFrom(); if (mf > mt) head = add(head, new StringRule(s.substring(mt, mf))); String var = null; if ((var = gv.stringMatched(1 + off)) != null || (var = gv.stringMatched(2 + off)) != null || (var = gv.stringMatched(5 + off)) != null) { int d = 0; for (int i = 0; i < var.length(); i++) d = 8 * d + (var.charAt(i) - '0'); if (var.length() == 1) head = add(head, new BackRefRule(d)); else head = new StringRule("" + (char) d); } else if ((var = gv.stringMatched(10 + off)) != null) { if ("QELlUu".indexOf(var) >= 0) head = add(head, new CodeRule(var.charAt(0))); else head = add(head, new StringRule(var)); } else if ((var = gv.stringMatched(3 + off)) != null || (var = gv.stringMatched(4 + off)) != null || (var = gv.stringMatched(6 + off)) != null) { String arg = ""; int pc; if ((pc = var.indexOf(':')) > 0) { arg = var.substring(pc + 1); var = var.substring(0, pc); } if (var.equals("&") || var.equals("MATCH")) { head = add(head, new AmpersandRule()); } else if (var.equals("`") || var.equals("PREMATCH")) { head = add(head, new LeftRule()); } else if (var.equals("'") || var.equals("POSTMATCH")) { head = add(head, new RightRule()); } else if (var.equals("WANT_MORE_TEXT")) { head = add(head, new WantMoreTextReplaceRule()); } else if (var.equals("POP")) { head = add(head, new PopRule()); } else if (var.startsWith("+") && (tmp = defs.get(var.substring(1))) != null) { if (tmp instanceof Regex) head = add(head, new PushRule(var.substring(1), (Regex) tmp)); else if (tmp instanceof Transformer) head = add(head, new PushRule(var.substring(1), (Transformer) tmp)); else head = add(head, new StringRule("${" + var + "}")); } else if (var.startsWith("=") && (tmp = defs.get(var.substring(1))) != null) { if (tmp instanceof Regex) head = add(head, new ChangeRule(var.substring(1), (Regex) tmp)); else if (tmp instanceof Transformer) head = add(head, new ChangeRule(var.substring(1), (Transformer) tmp)); else head = add(head, new StringRule("${" + var + "}")); } else if ((tmp = defs.get(var)) != null) { if (tmp instanceof ReplaceRule) { ReplaceRule alt = ((ReplaceRule) tmp).arg(arg); if (alt == null) alt = ((ReplaceRule) tmp); head = add(head, (ReplaceRule) (alt.clone())); } } else // can't figure out how to transform this thing... head = add(head, new StringRule("${" + var + "}")); } else if ((var = gv.stringMatched(7 + off)) != null) { char c = var.charAt(0); if (c == 'n') head = add(head, new StringRule("\n")); else if (c == 't') head = add(head, new StringRule("\t")); else if (c == 'r') head = add(head, new StringRule("\r")); else if (c == 'b') head = add(head, new StringRule("\r")); else if (c == 'a') head = add(head, new StringRule("" + (char) 7)); else if (c == 'e') head = add(head, new StringRule("" + (char) 27)); else if (c == 'f') head = add(head, new StringRule("" + (char) 12)); } else if ((var = gv.stringMatched(8 + off)) != null) { char c = var.charAt(0); if (c < Ctrl.cmap.length) c = Ctrl.cmap[c]; head = add(head, new StringRule("" + c)); } else if ((var = gv.stringMatched(9 + off)) != null) { int d = 16 * getHexDigit(var.charAt(0)) + getHexDigit(var.charAt(1)); head = add(head, new StringRule("" + (char) d)); } mt = gv.matchedTo(); } if (mt <= s.length()) head = add(head, new StringRule(s.substring(mt))); return head; } finally { // Regex.backGs = sav_backGs; // Regex.backGto = sav_backGto; } }