mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 07:14:30 +02:00
8065554: MatchResult should provide values of named-capturing groups
Reviewed-by: smarks
This commit is contained in:
parent
1decdcee71
commit
ce85cac947
4 changed files with 619 additions and 52 deletions
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -27,6 +27,7 @@ package java.util.regex;
|
|||
|
||||
import java.util.ConcurrentModificationException;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Objects;
|
||||
import java.util.Spliterator;
|
||||
|
@ -229,6 +230,8 @@ public final class Matcher implements MatchResult {
|
|||
*/
|
||||
int modCount;
|
||||
|
||||
private Map<String, Integer> namedGroups;
|
||||
|
||||
/**
|
||||
* No default constructor.
|
||||
*/
|
||||
|
@ -278,7 +281,8 @@ public final class Matcher implements MatchResult {
|
|||
this.last,
|
||||
groupCount(),
|
||||
this.groups.clone(),
|
||||
text);
|
||||
text,
|
||||
namedGroups());
|
||||
}
|
||||
|
||||
private static class ImmutableMatchResult implements MatchResult {
|
||||
|
@ -287,15 +291,18 @@ public final class Matcher implements MatchResult {
|
|||
private final int[] groups;
|
||||
private final int groupCount;
|
||||
private final String text;
|
||||
private final Map<String, Integer> namedGroups;
|
||||
|
||||
ImmutableMatchResult(int first, int last, int groupCount,
|
||||
int[] groups, String text)
|
||||
int[] groups, String text,
|
||||
Map<String, Integer> namedGroups)
|
||||
{
|
||||
this.first = first;
|
||||
this.last = last;
|
||||
this.groupCount = groupCount;
|
||||
this.groups = groups;
|
||||
this.text = text;
|
||||
this.namedGroups = namedGroups;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -307,8 +314,7 @@ public final class Matcher implements MatchResult {
|
|||
@Override
|
||||
public int start(int group) {
|
||||
checkMatch();
|
||||
if (group < 0 || group > groupCount)
|
||||
throw new IndexOutOfBoundsException("No group " + group);
|
||||
checkGroup(group);
|
||||
return groups[group * 2];
|
||||
}
|
||||
|
||||
|
@ -321,8 +327,7 @@ public final class Matcher implements MatchResult {
|
|||
@Override
|
||||
public int end(int group) {
|
||||
checkMatch();
|
||||
if (group < 0 || group > groupCount)
|
||||
throw new IndexOutOfBoundsException("No group " + group);
|
||||
checkGroup(group);
|
||||
return groups[group * 2 + 1];
|
||||
}
|
||||
|
||||
|
@ -340,18 +345,33 @@ public final class Matcher implements MatchResult {
|
|||
@Override
|
||||
public String group(int group) {
|
||||
checkMatch();
|
||||
if (group < 0 || group > groupCount)
|
||||
throw new IndexOutOfBoundsException("No group " + group);
|
||||
if ((groups[group*2] == -1) || (groups[group*2+1] == -1))
|
||||
checkGroup(group);
|
||||
if ((groups[group * 2] == -1) || (groups[group * 2 + 1] == -1))
|
||||
return null;
|
||||
return text.subSequence(groups[group * 2], groups[group * 2 + 1]).toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Integer> namedGroups() {
|
||||
return namedGroups;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasMatch() {
|
||||
return first >= 0;
|
||||
}
|
||||
|
||||
private void checkGroup(int group) {
|
||||
if (group < 0 || group > groupCount)
|
||||
throw new IndexOutOfBoundsException("No group " + group);
|
||||
}
|
||||
|
||||
private void checkMatch() {
|
||||
if (first < 0)
|
||||
if (!hasMatch())
|
||||
throw new IllegalStateException("No match found");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -446,8 +466,7 @@ public final class Matcher implements MatchResult {
|
|||
* or if the previous match operation failed
|
||||
*/
|
||||
public int start() {
|
||||
if (first < 0)
|
||||
throw new IllegalStateException("No match available");
|
||||
checkMatch();
|
||||
return first;
|
||||
}
|
||||
|
||||
|
@ -476,10 +495,8 @@ public final class Matcher implements MatchResult {
|
|||
* with the given index
|
||||
*/
|
||||
public int start(int group) {
|
||||
if (first < 0)
|
||||
throw new IllegalStateException("No match available");
|
||||
if (group < 0 || group > groupCount())
|
||||
throw new IndexOutOfBoundsException("No group " + group);
|
||||
checkMatch();
|
||||
checkGroup(group);
|
||||
return groups[group * 2];
|
||||
}
|
||||
|
||||
|
@ -518,8 +535,7 @@ public final class Matcher implements MatchResult {
|
|||
* or if the previous match operation failed
|
||||
*/
|
||||
public int end() {
|
||||
if (first < 0)
|
||||
throw new IllegalStateException("No match available");
|
||||
checkMatch();
|
||||
return last;
|
||||
}
|
||||
|
||||
|
@ -548,10 +564,8 @@ public final class Matcher implements MatchResult {
|
|||
* with the given index
|
||||
*/
|
||||
public int end(int group) {
|
||||
if (first < 0)
|
||||
throw new IllegalStateException("No match available");
|
||||
if (group < 0 || group > groupCount())
|
||||
throw new IndexOutOfBoundsException("No group " + group);
|
||||
checkMatch();
|
||||
checkGroup(group);
|
||||
return groups[group * 2 + 1];
|
||||
}
|
||||
|
||||
|
@ -640,10 +654,8 @@ public final class Matcher implements MatchResult {
|
|||
* with the given index
|
||||
*/
|
||||
public String group(int group) {
|
||||
if (first < 0)
|
||||
throw new IllegalStateException("No match found");
|
||||
if (group < 0 || group > groupCount())
|
||||
throw new IndexOutOfBoundsException("No group " + group);
|
||||
checkMatch();
|
||||
checkGroup(group);
|
||||
if ((groups[group*2] == -1) || (groups[group*2+1] == -1))
|
||||
return null;
|
||||
return getSubSequence(groups[group * 2], groups[group * 2 + 1]).toString();
|
||||
|
@ -900,9 +912,7 @@ public final class Matcher implements MatchResult {
|
|||
* that does not exist in the pattern
|
||||
*/
|
||||
public Matcher appendReplacement(StringBuffer sb, String replacement) {
|
||||
// If no match, return error
|
||||
if (first < 0)
|
||||
throw new IllegalStateException("No match available");
|
||||
checkMatch();
|
||||
StringBuilder result = new StringBuilder();
|
||||
appendExpandedReplacement(replacement, result);
|
||||
// Append the intervening text
|
||||
|
@ -991,8 +1001,7 @@ public final class Matcher implements MatchResult {
|
|||
*/
|
||||
public Matcher appendReplacement(StringBuilder sb, String replacement) {
|
||||
// If no match, return error
|
||||
if (first < 0)
|
||||
throw new IllegalStateException("No match available");
|
||||
checkMatch();
|
||||
StringBuilder result = new StringBuilder();
|
||||
appendExpandedReplacement(replacement, result);
|
||||
// Append the intervening text
|
||||
|
@ -1055,10 +1064,10 @@ public final class Matcher implements MatchResult {
|
|||
throw new IllegalArgumentException(
|
||||
"capturing group name {" + gname +
|
||||
"} starts with digit character");
|
||||
if (!parentPattern.namedGroups().containsKey(gname))
|
||||
if (!namedGroups().containsKey(gname))
|
||||
throw new IllegalArgumentException(
|
||||
"No group with name {" + gname + "}");
|
||||
refNum = parentPattern.namedGroups().get(gname);
|
||||
refNum = namedGroups().get(gname);
|
||||
cursor++;
|
||||
} else {
|
||||
// The first number is always a group
|
||||
|
@ -1796,10 +1805,47 @@ public final class Matcher implements MatchResult {
|
|||
*/
|
||||
int getMatchedGroupIndex(String name) {
|
||||
Objects.requireNonNull(name, "Group name");
|
||||
if (first < 0)
|
||||
throw new IllegalStateException("No match found");
|
||||
if (!parentPattern.namedGroups().containsKey(name))
|
||||
checkMatch();
|
||||
if (!namedGroups().containsKey(name))
|
||||
throw new IllegalArgumentException("No group with name <" + name + ">");
|
||||
return parentPattern.namedGroups().get(name);
|
||||
return namedGroups().get(name);
|
||||
}
|
||||
|
||||
private void checkGroup(int group) {
|
||||
if (group < 0 || group > groupCount())
|
||||
throw new IndexOutOfBoundsException("No group " + group);
|
||||
}
|
||||
|
||||
private void checkMatch() {
|
||||
if (!hasMatch())
|
||||
throw new IllegalStateException("No match found");
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @return {@inheritDoc}
|
||||
*
|
||||
* @since {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Map<String, Integer> namedGroups() {
|
||||
if (namedGroups == null) {
|
||||
return namedGroups = parentPattern.namedGroups();
|
||||
}
|
||||
return namedGroups;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @return {@inheritDoc}
|
||||
*
|
||||
* @since {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean hasMatch() {
|
||||
return first >= 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue