-
Bug
-
Resolution: Fixed
-
P4
-
1.4.0
-
beta3
-
generic
-
generic
-
Verified
Name: nt126004 Date: 10/02/2001
java version "1.4.0-beta2"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-beta2-b77)
Java HotSpot(TM) Client VM (build 1.4.0-beta2-b77, mixed mode)
The method appendReplacement(StringBuffer sb, String replacement) doesn't parse
group references properly. Although most calls to this method won't be affected
by the bug, it becomes obvious in two situations:
1. The regex contains more than 9 groups and the replacement string contains a
reference to group 10 or higher ($10, $11...)
2. When the last character of the replacement string comes right after a group
reference it will be ignored. E.g. replace if the regex is "(.)" and we attempt
to replace "X" by "($1)", the actual replacement will be "(X".
This bug is very easy to fix.
Make changes to the code in the inner while loop of appendReplacement()'s
parsing routine:
while (!done) {
cursor++;
^^^^^^^^^ <-- remove
groupEnd = cursor;
if (cursor >= replacement.length())
break;
int nextDigit = replacement.charAt(cursor) - '0';
if ((nextDigit < 0)||(nextDigit > 9)) { // not a number
cursor--;
^^^^^^^^^ <-- remove
break;
}
int newRefNum = (refNum * 10) + nextDigit;
if (groupCount() < newRefNum)
done = true;
else
refNum = newRefNum;
cursor++;
^^^^^^^^^ <-- add
}
import java.util.regex.*;
class TestRegexReplacement
{
public void testMoreThanNineMatchGroups() {
String haystack = "Here is dozenletters!";
// following pattern has twelve groups, each maches one character
// of the word dozenletters
String pattern =
".*(\\w)(\\w)(\\w)(\\w)(\\w)(\\w)(\\w)(\\w)(\\w)(\\w)(\\w)(\\w)";
String replacement = "You are $12$10$9";
String expected = "You are set!";
Pattern p = Pattern.compile( pattern );
Matcher m = p.matcher( haystack );
// execute the regex search n' replace
StringBuffer sb = new StringBuffer();
m.find();
m.appendReplacement( sb, replacement );
m.appendTail( sb );
System.out.println( "\ntestMoreThanNineMatchGroups()\n" +
"-------------------------------" );
System.out.println(
"Should change \"" + haystack + "\"" +
" into: \"" + expected + "\"" );
System.out.println( "But actually changes it into: \"" + sb + "\"\n" );
}
public void testLastCharacterIgnored() {
String haystack = "__-x-__";
String pattern = "-(.)-"; // find this needle in haystack
String replacement = "|$1|"; // replace it with this one
String expected = "__|x|__"; // expected outcome
Pattern p = Pattern.compile( pattern );
Matcher m = p.matcher( haystack );
// execute the regex search n' replace
StringBuffer sb = new StringBuffer();
m.find();
m.appendReplacement( sb, replacement );
m.appendTail( sb );
System.out.println( "\ntestLastCharacterIgnored()\n" +
"-------------------------------" );
System.out.println(
"Should change \"" + haystack + "\"" +
" into: \"" + expected + "\"" );
System.out.println( "But actually changes it into: \"" + sb + "\"\n" );
}
public static void main(String[] args) {
TestRegexReplacement test = new TestRegexReplacement();
test.testLastCharacterIgnored();
test.testMoreThanNineMatchGroups();
}
}
(Review ID: 132875)
======================================================================