diff --git a/jdk/src/share/classes/java/util/regex/Matcher.java b/jdk/src/share/classes/java/util/regex/Matcher.java
index 488e47da89a..76883d930c7 100644
--- a/jdk/src/share/classes/java/util/regex/Matcher.java
+++ b/jdk/src/share/classes/java/util/regex/Matcher.java
@@ -688,7 +688,7 @@ public final class Matcher implements MatchResult {
*
*
The replacement string may contain references to subsequences
* captured during the previous match: Each occurrence of
- * $<name> or $g
+ * ${name} or $g
* will be replaced by the result of evaluating the corresponding
* {@link #group(String) group(name)} or {@link #group(int) group(g)}
* respectively. For $g,
@@ -770,7 +770,7 @@ public final class Matcher implements MatchResult {
// more appropriate.
nextChar = replacement.charAt(cursor);
int refNum = -1;
- if (nextChar == '<') {
+ if (nextChar == '{') {
cursor++;
StringBuilder gsb = new StringBuilder();
while (cursor < replacement.length()) {
@@ -787,13 +787,17 @@ public final class Matcher implements MatchResult {
if (gsb.length() == 0)
throw new IllegalArgumentException(
"named capturing group has 0 length name");
- if (nextChar != '>')
+ if (nextChar != '}')
throw new IllegalArgumentException(
- "named capturing group is missing trailing '>'");
+ "named capturing group is missing trailing '}'");
String gname = gsb.toString();
+ if (ASCII.isDigit(gname.charAt(0)))
+ throw new IllegalArgumentException(
+ "capturing group name {" + gname +
+ "} starts with digit character");
if (!parentPattern.namedGroups().containsKey(gname))
throw new IllegalArgumentException(
- "No group with name <" + gname + ">");
+ "No group with name {" + gname + "}");
refNum = parentPattern.namedGroups().get(gname);
cursor++;
} else {
diff --git a/jdk/src/share/classes/java/util/regex/Pattern.java b/jdk/src/share/classes/java/util/regex/Pattern.java
index bda83849a37..a69c8da669f 100644
--- a/jdk/src/share/classes/java/util/regex/Pattern.java
+++ b/jdk/src/share/classes/java/util/regex/Pattern.java
@@ -484,7 +484,7 @@ import java.util.Arrays;
*
Group name
* A capturing group can also be assigned a "name", a named-capturing group,
* and then be back-referenced later by the "name". Group names are composed of
- * the following characters:
+ * the following characters. The first character must be a letter.
*
*
* - The uppercase letters 'A' through 'Z'
@@ -2567,7 +2567,7 @@ loop: for(int x=0, offset=0; xy+)z+"),
+ check(Pattern.compile("x+(?y+)z+"),
"xxxyyyzzz",
- "8gname",
+ "gname8",
"yyy");
//backref
@@ -3430,81 +3430,82 @@ public class RegExTest {
//replaceFirst/All
checkReplaceFirst("(?ab)(c*)",
"abccczzzabcczzzabccc",
- "$",
+ "${gn}",
"abzzzabcczzzabccc");
checkReplaceAll("(?ab)(c*)",
"abccczzzabcczzzabccc",
- "$",
+ "${gn}",
"abzzzabzzzab");
checkReplaceFirst("(?ab)(c*)",
"zzzabccczzzabcczzzabccczzz",
- "$",
+ "${gn}",
"zzzabzzzabcczzzabccczzz");
checkReplaceAll("(?ab)(c*)",
"zzzabccczzzabcczzzabccczzz",
- "$",
+ "${gn}",
"zzzabzzzabzzzabzzz");
checkReplaceFirst("(?ab)(?c*)",
"zzzabccczzzabcczzzabccczzz",
- "$",
+ "${gn2}",
"zzzccczzzabcczzzabccczzz");
checkReplaceAll("(?ab)(?c*)",
"zzzabccczzzabcczzzabccczzz",
- "$",
+ "${gn2}",
"zzzccczzzcczzzccczzz");
//toSupplementaries("(ab)(c*)"));
checkReplaceFirst("(?" + toSupplementaries("ab") +
")(?" + toSupplementaries("c") + "*)",
toSupplementaries("abccczzzabcczzzabccc"),
- "$",
+ "${gn1}",
toSupplementaries("abzzzabcczzzabccc"));
checkReplaceAll("(?" + toSupplementaries("ab") +
")(?" + toSupplementaries("c") + "*)",
toSupplementaries("abccczzzabcczzzabccc"),
- "$",
+ "${gn1}",
toSupplementaries("abzzzabzzzab"));
checkReplaceFirst("(?" + toSupplementaries("ab") +
")(?" + toSupplementaries("c") + "*)",
toSupplementaries("abccczzzabcczzzabccc"),
- "$",
+ "${gn2}",
toSupplementaries("ccczzzabcczzzabccc"));
checkReplaceAll("(?" + toSupplementaries("ab") +
")(?" + toSupplementaries("c") + "*)",
toSupplementaries("abccczzzabcczzzabccc"),
- "$",
+ "${gn2}",
toSupplementaries("ccczzzcczzzccc"));
checkReplaceFirst("(?Dog)AndCat",
"zzzDogAndCatzzzDogAndCatzzz",
- "$",
+ "${dog}",
"zzzDogzzzDogAndCatzzz");
checkReplaceAll("(?Dog)AndCat",
"zzzDogAndCatzzzDogAndCatzzz",
- "$",
+ "${dog}",
"zzzDogzzzDogzzz");
// backref in Matcher & String
- if (!"abcdefghij".replaceFirst("cd(?ef)gh", "$").equals("abefij") ||
- !"abbbcbdbefgh".replaceAll("(?[a-e])b", "$").equals("abcdefgh"))
+ if (!"abcdefghij".replaceFirst("cd(?ef)gh", "${gn}").equals("abefij") ||
+ !"abbbcbdbefgh".replaceAll("(?[a-e])b", "${gn}").equals("abcdefgh"))
failCount++;
// negative
checkExpectedFail("(?abc)(def)");
checkExpectedFail("(?abc)(def)");
+ checkExpectedFail("(?<6groupnamestartswithdigit>abc)(def)");
checkExpectedFail("(?abc)(def)\\k");
checkExpectedFail("(?abc)(?def)\\k");
checkExpectedFail(Pattern.compile("(?abc)(def)").matcher("abcdef"),