1
1
/*
2
- * Copyright (c) 2003, 2013 , Oracle and/or its affiliates. All rights reserved.
2
+ * Copyright (c) 2003, 2022 , Oracle and/or its affiliates. All rights reserved.
3
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
4
*
5
5
* This code is free software; you can redistribute it and/or modify it
25
25
26
26
package java .util .regex ;
27
27
28
+ import java .util .Map ;
29
+ import java .util .Objects ;
30
+
28
31
/**
29
32
* The result of a match operation.
30
33
*
33
36
* groups and group boundaries can be seen but not modified through
34
37
* a {@code MatchResult}.
35
38
*
39
+ * @implNote
40
+ * Support for named groups is implemented by the default methods
41
+ * {@link #start(String)}, {@link #end(String)} and {@link #group(String)}.
42
+ * They all make use of the map returned by {@link #namedGroups()}, whose
43
+ * default implementation simply throws {@link UnsupportedOperationException}.
44
+ * It is thus sufficient to override {@link #namedGroups()} for these methods
45
+ * to work. However, overriding them directly might be preferable for
46
+ * performance or other reasons.
47
+ *
36
48
* @author Michael McCloskey
37
49
* @see Matcher
38
50
* @since 1.5
@@ -48,7 +60,7 @@ public interface MatchResult {
48
60
* If no match has yet been attempted,
49
61
* or if the previous match operation failed
50
62
*/
51
- public int start ();
63
+ int start ();
52
64
53
65
/**
54
66
* Returns the start index of the subsequence captured by the given group
@@ -74,7 +86,38 @@ public interface MatchResult {
74
86
* If there is no capturing group in the pattern
75
87
* with the given index
76
88
*/
77
- public int start (int group );
89
+ int start (int group );
90
+
91
+ /**
92
+ * Returns the start index of the subsequence captured by the given
93
+ * <a href="Pattern.html#groupname">named-capturing group</a> during the
94
+ * previous match operation.
95
+ *
96
+ * @param name
97
+ * The name of a named-capturing group in this matcher's pattern
98
+ *
99
+ * @return The index of the first character captured by the group,
100
+ * or {@code -1} if the match was successful but the group
101
+ * itself did not match anything
102
+ *
103
+ * @throws IllegalStateException
104
+ * If no match has yet been attempted,
105
+ * or if the previous match operation failed
106
+ *
107
+ * @throws IllegalArgumentException
108
+ * If there is no capturing group in the pattern
109
+ * with the given name
110
+ *
111
+ * @implSpec
112
+ * The default implementation of this method invokes {@link #namedGroups()}
113
+ * to obtain the group number from the {@code name} argument, and uses it
114
+ * as argument to an invocation of {@link #start(int)}.
115
+ *
116
+ * @since 20
117
+ */
118
+ default int start (String name ) {
119
+ return start (groupNumber (name ));
120
+ }
78
121
79
122
/**
80
123
* Returns the offset after the last character matched.
@@ -85,7 +128,7 @@ public interface MatchResult {
85
128
* If no match has yet been attempted,
86
129
* or if the previous match operation failed
87
130
*/
88
- public int end ();
131
+ int end ();
89
132
90
133
/**
91
134
* Returns the offset after the last character of the subsequence
@@ -111,7 +154,38 @@ public interface MatchResult {
111
154
* If there is no capturing group in the pattern
112
155
* with the given index
113
156
*/
114
- public int end (int group );
157
+ int end (int group );
158
+
159
+ /**
160
+ * Returns the offset after the last character of the subsequence
161
+ * captured by the given <a href="Pattern.html#groupname">named-capturing
162
+ * group</a> during the previous match operation.
163
+ *
164
+ * @param name
165
+ * The name of a named-capturing group in this matcher's pattern
166
+ *
167
+ * @return The offset after the last character captured by the group,
168
+ * or {@code -1} if the match was successful
169
+ * but the group itself did not match anything
170
+ *
171
+ * @throws IllegalStateException
172
+ * If no match has yet been attempted,
173
+ * or if the previous match operation failed
174
+ *
175
+ * @throws IllegalArgumentException
176
+ * If there is no capturing group in the pattern
177
+ * with the given name
178
+ *
179
+ * @implSpec
180
+ * The default implementation of this method invokes {@link #namedGroups()}
181
+ * to obtain the group number from the {@code name} argument, and uses it
182
+ * as argument to an invocation of {@link #end(int)}.
183
+ *
184
+ * @since 20
185
+ */
186
+ default int end (String name ) {
187
+ return end (groupNumber (name ));
188
+ }
115
189
116
190
/**
117
191
* Returns the input subsequence matched by the previous match.
@@ -132,7 +206,7 @@ public interface MatchResult {
132
206
* If no match has yet been attempted,
133
207
* or if the previous match operation failed
134
208
*/
135
- public String group ();
209
+ String group ();
136
210
137
211
/**
138
212
* Returns the input subsequence captured by the given group during the
@@ -170,7 +244,44 @@ public interface MatchResult {
170
244
* If there is no capturing group in the pattern
171
245
* with the given index
172
246
*/
173
- public String group (int group );
247
+ String group (int group );
248
+
249
+ /**
250
+ * Returns the input subsequence captured by the given
251
+ * <a href="Pattern.html#groupname">named-capturing group</a> during the
252
+ * previous match operation.
253
+ *
254
+ * <p> If the match was successful but the group specified failed to match
255
+ * any part of the input sequence, then {@code null} is returned. Note
256
+ * that some groups, for example {@code (a*)}, match the empty string.
257
+ * This method will return the empty string when such a group successfully
258
+ * matches the empty string in the input. </p>
259
+ *
260
+ * @param name
261
+ * The name of a named-capturing group in this matcher's pattern
262
+ *
263
+ * @return The (possibly empty) subsequence captured by the named group
264
+ * during the previous match, or {@code null} if the group
265
+ * failed to match part of the input
266
+ *
267
+ * @throws IllegalStateException
268
+ * If no match has yet been attempted,
269
+ * or if the previous match operation failed
270
+ *
271
+ * @throws IllegalArgumentException
272
+ * If there is no capturing group in the pattern
273
+ * with the given name
274
+ *
275
+ * @implSpec
276
+ * The default implementation of this method invokes {@link #namedGroups()}
277
+ * to obtain the group number from the {@code name} argument, and uses it
278
+ * as argument to an invocation of {@link #group(int)}.
279
+ *
280
+ * @since 20
281
+ */
282
+ default String group (String name ) {
283
+ return group (groupNumber (name ));
284
+ }
174
285
175
286
/**
176
287
* Returns the number of capturing groups in this match result's pattern.
@@ -184,6 +295,55 @@ public interface MatchResult {
184
295
*
185
296
* @return The number of capturing groups in this matcher's pattern
186
297
*/
187
- public int groupCount ();
298
+ int groupCount ();
299
+
300
+ /**
301
+ * Returns an unmodifiable map from capturing group names to group numbers.
302
+ * If there are no named groups, returns an empty map.
303
+ *
304
+ * @return an unmodifiable map from capturing group names to group numbers
305
+ *
306
+ * @throws UnsupportedOperationException if the implementation does not
307
+ * support named groups.
308
+ *
309
+ * @implSpec The default implementation of this method always throws
310
+ * {@link UnsupportedOperationException}
311
+ *
312
+ * @apiNote
313
+ * This method must be overridden by an implementation that supports
314
+ * named groups.
315
+ *
316
+ * @since 20
317
+ */
318
+ default Map <String ,Integer > namedGroups () {
319
+ throw new UnsupportedOperationException ("namedGroups()" );
320
+ }
321
+
322
+ private int groupNumber (String name ) {
323
+ Objects .requireNonNull (name , "Group name" );
324
+ Integer number = namedGroups ().get (name );
325
+ if (number != null ) {
326
+ return number ;
327
+ }
328
+ throw new IllegalArgumentException ("No group with name <" + name + ">" );
329
+ }
330
+
331
+ /**
332
+ * Returns whether {@code this} contains a valid match from
333
+ * a previous match or find operation.
334
+ *
335
+ * @return whether {@code this} contains a valid match
336
+ *
337
+ * @throws UnsupportedOperationException if the implementation cannot report
338
+ * whether it has a match
339
+ *
340
+ * @implSpec The default implementation of this method always throws
341
+ * {@link UnsupportedOperationException}
342
+ *
343
+ * @since 20
344
+ */
345
+ default boolean hasMatch () {
346
+ throw new UnsupportedOperationException ("hasMatch()" );
347
+ }
188
348
189
349
}
0 commit comments