/** * Compile a regular expression using the JDK implementation */ @Test public void testMatcher() { final RegExp regexp = new RegExpFactory().compile("f(o)o", ""); final RegExpMatcher matcher = regexp.match("foo"); assertNotNull(matcher); assertTrue(matcher.search(0)); assertEquals(matcher.getInput(), "foo"); assertEquals(matcher.groupCount(), 1); assertEquals(matcher.group(), "foo"); assertEquals(matcher.start(), 0); assertEquals(matcher.end(), 3); assertEquals(matcher.group(1), "o"); assertEquals(matcher.start(1), 1); assertEquals(matcher.end(1), 2); }
private String callReplaceValue(final MethodHandle invoker, final ScriptFunction function, final Object self, final RegExpMatcher matcher, final String string) throws Throwable { final Object[] groups = groups(matcher); final Object[] args = Arrays.copyOf(groups, groups.length + 2); args[groups.length] = matcher.start(); args[groups.length + 1] = string; return (String)invoker.invokeExact(function, self, args); }
private String callReplaceValue(final MethodHandle invoker, final Object function, final Object self, final RegExpMatcher matcher, final String string) throws Throwable { final Object[] groups = groups(matcher); final Object[] args = Arrays.copyOf(groups, groups.length + 2); args[groups.length] = matcher.start(); args[groups.length + 1] = string; return (String)invoker.invokeExact(function, self, args); }
private String callReplaceValue(final ScriptFunction function, final RegExpMatcher matcher, final String string) { final Object[] groups = groups(matcher); final Object[] args = Arrays.copyOf(groups, groups.length + 2); args[groups.length] = matcher.start(); args[groups.length + 1] = string; final Object self = function.isStrict() ? UNDEFINED : Global.instance(); return JSType.toString(ScriptRuntime.apply(function, self, args)); }
private void appendReplacement(final RegExpMatcher matcher, final String text, final String replacement, final StringBuilder sb) { /* * Process substitution patterns: * * $$ -> $ * $& -> the matched substring * $` -> the portion of string that preceeds matched substring * $' -> the portion of string that follows the matched substring * $n -> the nth capture, where n is [1-9] and $n is NOT followed by a decimal digit * $nn -> the nnth capture, where nn is a two digit decimal number [01-99]. */ int cursor = 0; Object[] groups = null; while (cursor < replacement.length()) { char nextChar = replacement.charAt(cursor); if (nextChar == '$') { // Skip past $ cursor++; if (cursor == replacement.length()) { // nothing after "$" sb.append('$'); break; } nextChar = replacement.charAt(cursor); final int firstDigit = nextChar - '0'; if (firstDigit >= 0 && firstDigit <= 9 && firstDigit <= matcher.groupCount()) { // $0 is not supported, but $01 is. implementation-defined: if n>m, ignore second digit. int refNum = firstDigit; cursor++; if (cursor < replacement.length() && firstDigit < matcher.groupCount()) { final int secondDigit = replacement.charAt(cursor) - '0'; if (secondDigit >= 0 && secondDigit <= 9) { final int newRefNum = firstDigit * 10 + secondDigit; if (newRefNum <= matcher.groupCount() && newRefNum > 0) { // $nn ($01-$99) refNum = newRefNum; cursor++; } } } if (refNum > 0) { if (groups == null) { groups = groups(matcher); } // Append group if matched. if (groups[refNum] != UNDEFINED) { sb.append((String) groups[refNum]); } } else { // $0. ignore. assert refNum == 0; sb.append("$0"); } } else if (nextChar == '$') { sb.append('$'); cursor++; } else if (nextChar == '&') { sb.append(matcher.group()); cursor++; } else if (nextChar == '`') { sb.append(text, 0, matcher.start()); cursor++; } else if (nextChar == '\'') { sb.append(text, matcher.end(), text.length()); cursor++; } else { // unknown substitution or $n with n>m. skip. sb.append('$'); } } else { sb.append(nextChar); cursor++; } } }
private void appendReplacement(final RegExpMatcher matcher, final String text, final String replacement, final StringBuilder sb) { /* * Process substitution patterns: * * $$ -> $ * $& -> the matched substring * $` -> the portion of string that precedes matched substring * $' -> the portion of string that follows the matched substring * $n -> the nth capture, where n is [1-9] and $n is NOT followed by a decimal digit * $nn -> the nnth capture, where nn is a two digit decimal number [01-99]. */ int cursor = 0; Object[] groups = null; while (cursor < replacement.length()) { char nextChar = replacement.charAt(cursor); if (nextChar == '$') { // Skip past $ cursor++; if (cursor == replacement.length()) { // nothing after "$" sb.append('$'); break; } nextChar = replacement.charAt(cursor); final int firstDigit = nextChar - '0'; if (firstDigit >= 0 && firstDigit <= 9 && firstDigit <= matcher.groupCount()) { // $0 is not supported, but $01 is. implementation-defined: if n>m, ignore second digit. int refNum = firstDigit; cursor++; if (cursor < replacement.length() && firstDigit < matcher.groupCount()) { final int secondDigit = replacement.charAt(cursor) - '0'; if (secondDigit >= 0 && secondDigit <= 9) { final int newRefNum = firstDigit * 10 + secondDigit; if (newRefNum <= matcher.groupCount() && newRefNum > 0) { // $nn ($01-$99) refNum = newRefNum; cursor++; } } } if (refNum > 0) { if (groups == null) { groups = groups(matcher); } // Append group if matched. if (groups[refNum] != UNDEFINED) { sb.append((String) groups[refNum]); } } else { // $0. ignore. assert refNum == 0; sb.append("$0"); } } else if (nextChar == '$') { sb.append('$'); cursor++; } else if (nextChar == '&') { sb.append(matcher.group()); cursor++; } else if (nextChar == '`') { sb.append(text, 0, matcher.start()); cursor++; } else if (nextChar == '\'') { sb.append(text, matcher.end(), text.length()); cursor++; } else { // unknown substitution or $n with n>m. skip. sb.append('$'); } } else { sb.append(nextChar); cursor++; } } }
private void appendReplacement(final RegExpMatcher matcher, final String text, final String replacement, final StringBuilder sb) { /* * Process substitution patterns: * * $$ -> $ * $& -> the matched substring * $` -> the portion of string that preceeds matched substring * $' -> the portion of string that follows the matched substring * $n -> the nth capture, where n is [1-9] and $n is NOT followed by a decimal digit * $nn -> the nnth capture, where nn is a two digit decimal number [01-99]. */ int cursor = 0; Object[] groups = null; while (cursor < replacement.length()) { char nextChar = replacement.charAt(cursor); if (nextChar == '$') { // Skip past $ cursor++; nextChar = replacement.charAt(cursor); final int firstDigit = nextChar - '0'; if (firstDigit >= 0 && firstDigit <= 9 && firstDigit <= matcher.groupCount()) { // $0 is not supported, but $01 is. implementation-defined: if n>m, ignore second digit. int refNum = firstDigit; cursor++; if (cursor < replacement.length() && firstDigit < matcher.groupCount()) { final int secondDigit = replacement.charAt(cursor) - '0'; if ((secondDigit >= 0) && (secondDigit <= 9)) { final int newRefNum = (firstDigit * 10) + secondDigit; if (newRefNum <= matcher.groupCount() && newRefNum > 0) { // $nn ($01-$99) refNum = newRefNum; cursor++; } } } if (refNum > 0) { if (groups == null) { groups = groups(matcher); } // Append group if matched. if (groups[refNum] != UNDEFINED) { sb.append((String) groups[refNum]); } } else { // $0. ignore. assert refNum == 0; sb.append("$0"); } } else if (nextChar == '$') { sb.append('$'); cursor++; } else if (nextChar == '&') { sb.append(matcher.group()); cursor++; } else if (nextChar == '`') { sb.append(text, 0, matcher.start()); cursor++; } else if (nextChar == '\'') { sb.append(text, matcher.end(), text.length()); cursor++; } else { // unknown substitution or $n with n>m. skip. sb.append('$'); } } else { sb.append(nextChar); cursor++; } } }