Skip to content

Commit 2c43791

Browse files
authored
Merge pull request #74 from tony19/feat/named-groups-jdk20
feat!: rename MatchResult#namedGroups to avoid conflict in JDK 20
2 parents bd39b01 + 9552147 commit 2c43791

File tree

6 files changed

+111
-46
lines changed

6 files changed

+111
-46
lines changed

.github/workflows/ci.yml

Lines changed: 4 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@ on:
55
workflow_dispatch:
66

77
jobs:
8-
build-8-11:
9-
runs-on: ubuntu-22.04
8+
build:
9+
runs-on: ubuntu-latest
1010
strategy:
1111
matrix:
12-
jdk: [ '8', '9', '10', '11' ]
12+
jdk: [ '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21' ]
1313
name: JDK ${{ matrix.jdk }}
1414
steps:
1515
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4
@@ -18,20 +18,4 @@ jobs:
1818
distribution: 'zulu'
1919
java-version: ${{ matrix.jdk }}
2020
cache: 'maven'
21-
- run: mvn verify -Dgpg.skip -Dmaven.compiler.source=6 -Dmaven.compiler.target=6
22-
23-
# JDK12+ no longer supports JDK6 as source/target
24-
build-12-plus:
25-
runs-on: ubuntu-22.04
26-
strategy:
27-
matrix:
28-
jdk: [ '12', '13', '14', '15', '16', '17', '18' ]
29-
name: JDK ${{ matrix.jdk }}
30-
steps:
31-
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4
32-
- uses: actions/setup-java@v4
33-
with:
34-
distribution: 'zulu'
35-
java-version: ${{ matrix.jdk }}
36-
cache: 'maven'
37-
- run: mvn verify -Dgpg.skip -Dmaven.compiler.source=7 -Dmaven.compiler.target=7
21+
- run: mvn verify -Dgpg.skip

README.md

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
11
named-regexp [![GitHub release](https://img.shields.io/github/release/tony19/named-regexp.svg?maxAge=2592000)](https://github.com/tony19/named-regexp/releases/) [![Build](https://github.com/tony19/named-regexp/actions/workflows/ci.yml/badge.svg)](https://github.com/tony19/named-regexp/actions/workflows/ci.yml)
22
---
33

4-
This lightweight library adds support for [named capture groups](http://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html#groupname) in Java 5/6 (and on Android).
5-
6-
This is a fork of the [named-regexp](http://code.google.com/p/named-regexp) project from Google Code (currently inactive).
7-
4+
This library backports [named capture groups](http://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html#groupname) from Java 7 to Java 5/6.
85

96
Usage
107
-----
11-
You can use the same constructs for named capture groups from Java 7 (i.e., `(?<name>patt)`, etc.), as in the following example:
8+
You can use the same constructs for named capture groups from Java 7
9+
(i.e., `(?<name>patt)`, etc.), as in the following example:
1210

1311
```java
1412
import com.google.code.regexp.Pattern;
@@ -29,15 +27,15 @@ Install
2927

3028
### Gradle
3129
```gradle
32-
implementation 'com.github.tony19:named-regexp:0.2.8'
30+
implementation 'com.github.tony19:named-regexp:1.0.0'
3331
```
3432

3533
### Maven
3634
```xml
3735
<dependency>
3836
<groupId>com.github.tony19</groupId>
3937
<artifactId>named-regexp</artifactId>
40-
<version>0.2.8</version>
38+
<version>1.0.0</version>
4139
</dependency>
4240
```
4341

@@ -54,6 +52,10 @@ $ cd named-regexp
5452
$ mvn package
5553
```
5654

55+
To create Java 5/6 compatible bytecode, use JDK 11 or older to build this library.
56+
The build automatically targets Java 8 (the minimum supported version) if using a
57+
newer JDK to build.
58+
5759
Release
5860
-------
5961

@@ -65,7 +67,8 @@ $ ./release.sh
6567

6668
*Releases are deployed to https://repo1.maven.org/maven2/com/github/tony19/named-regexp/*
6769

68-
To release a `SNAPSHOT` (i.e., the version in `pom.xml` ends with `-SNAPSHOT`), run the following command:
70+
To release a `SNAPSHOT` (i.e., the version in `pom.xml` ends with `-SNAPSHOT`),
71+
run the following command:
6972

7073
```bash
7174
$ mvn clean deploy
@@ -76,7 +79,7 @@ $ mvn clean deploy
7679
License
7780
-------
7881

79-
Copyright 2022 Anthony Trinh.
82+
Copyright 2024 Anthony Trinh.
8083

8184
Licensed under the Apache License, Version 2.0 (the "License");
8285
you may not use this file except in compliance with the License.

pom.xml

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
<packaging>jar</packaging>
88
<name>named-regexp</name>
99
<description>Named capturing groups for Java 5/6</description>
10-
<version>0.2.9-SNAPSHOT</version>
10+
<version>1.0.0-SNAPSHOT</version>
1111
<url>https://github.com/tony19/named-regexp</url>
1212

1313
<licenses>
@@ -120,6 +120,20 @@
120120
</build>
121121

122122
<profiles>
123+
<profile>
124+
<!--
125+
If using JDK 12+, switch to Java 8 here (the minimum
126+
supported version). Some users that mainly depend on newer
127+
JDKS are still using this library for backward compatibility.
128+
-->
129+
<id>set-compiler-release</id>
130+
<activation>
131+
<jdk>[12,)</jdk>
132+
</activation>
133+
<properties>
134+
<maven.compiler.release>8</maven.compiler.release>
135+
</properties>
136+
</profile>
123137
<profile>
124138
<id>release-sign-artifacts</id>
125139
<activation>

src/main/java/com/google/code/regexp/MatchResult.java

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,33 @@ public interface MatchResult extends java.util.regex.MatchResult {
3737
public List<String> orderedGroups();
3838

3939
/**
40-
* Returns the named capture groups
40+
* Finds all named groups that exist in the input string
4141
*
42-
* @return the named capture groups
42+
* @return a list of maps, each containing name-value matches
43+
* (empty if no match found).
44+
*
45+
* Example:
46+
* pattern: (?&lt;dote&gt;\d+).(?&lt;day&gt;\w+)
47+
* input: 1 Sun foo bar 2 Mon foo
48+
* output: [{"date":"1", "day":"Sun"}, {"date":"2", "day":"Mon"}]
49+
*
50+
* @since 1.0.0
51+
*/
52+
public List<Map<String, String>> namedGroupsList();
53+
54+
/**
55+
* Returns a map of the pattern's named groups and indexes within the pattern.
56+
*
57+
* @return an unmodifiable map of group names to 1-based indexes
58+
* (empty if named groups not found).
59+
*
60+
* Example:
61+
* pattern: (a)(b)(?&lt;group1&gt;x)(c)(?&lt;group2&gt;y)
62+
* output: {"group1": 3, "group2": 5}
63+
*
64+
* @since 1.0.0
4365
*/
44-
public List<Map<String, String>> namedGroups();
66+
public Map<String, Integer> namedGroups();
4567

4668
/**
4769
* Returns the input subsequence captured by the given group during the

src/main/java/com/google/code/regexp/Matcher.java

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
package com.google.code.regexp;
1717

1818
import java.util.ArrayList;
19+
import java.util.Collections;
20+
import java.util.HashMap;
1921
import java.util.LinkedHashMap;
2022
import java.util.List;
2123
import java.util.Map;
@@ -298,6 +300,33 @@ public String group(String groupName) {
298300
return group(idx);
299301
}
300302

303+
/**
304+
* Returns a map of the pattern's named groups and indexes within the pattern.
305+
*
306+
* @return an unmodifiable map of group names to 1-based indexes
307+
* (empty if named groups not found).
308+
*
309+
* Example:
310+
* pattern: (a)(b)(?&lt;group1&gt;x)(c)(?&lt;group2&gt;y)
311+
* output: {"group1": 3, "group2": 5}
312+
*
313+
* @since 1.0.0
314+
*/
315+
public Map<String, Integer> namedGroups() {
316+
// Normally, this API isn't needed as this library is a backport
317+
// of named groups, introduced in JDK7, but some users are
318+
// using on this library in newer JDKs for whatever reason.
319+
// https://github.com/tony19/named-regexp/issues/73
320+
Map<String, Integer> result = new HashMap<String, Integer>();
321+
Map<String, List<GroupInfo>> groupInfo = parentPattern.groupInfo();
322+
323+
for (Map.Entry<String, List<GroupInfo>> entry : groupInfo.entrySet()) {
324+
// groupIndex() is 0-based and we need it 1-based for capture groups
325+
result.put(entry.getKey(), entry.getValue().get(0).groupIndex() + 1);
326+
}
327+
return Collections.unmodifiableMap(result);
328+
}
329+
301330
/**
302331
* Finds all named groups that exist in the input string. This resets the
303332
* matcher and attempts to match the input against the pre-specified
@@ -310,8 +339,10 @@ public String group(String groupName) {
310339
* pattern: (?&lt;dote&gt;\d+).(?&lt;day&gt;\w+)
311340
* input: 1 Sun foo bar 2 Mon foo
312341
* output: [{"date":"1", "day":"Sun"}, {"date":"2", "day":"Mon"}]
342+
*
343+
* @since 1.0.0
313344
*/
314-
public List<Map<String, String>> namedGroups() {
345+
public List<Map<String, String>> namedGroupsList() {
315346
List<Map<String, String>> result = new ArrayList<Map<String, String>>();
316347
List<String> groupNames = parentPattern.groupNames();
317348

src/test/java/com/google/code/regexp/MatcherTest.java

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ public void beforeTest() {
3939
}
4040

4141
@Test
42-
public void testFindSucceedsInFindingTaret() {
42+
public void testFindSucceedsInFindingTarget() {
4343
assertTrue(P.matcher("abcfoo").find());
4444
}
4545

@@ -279,7 +279,7 @@ public void testOrderedGroupsHasMatchesInOrder() {
279279

280280
@Test
281281
public void testNamedGroupsDoesNotThrowIndexOutOfBounds() {
282-
// NamedMatcher.namedGroups() is used to get a map of
282+
// Matcher#namedGroupsList() is used to get a map of
283283
// group names to group values. This should ignore unnamed
284284
// groups (exclude them from the map), but the unnamed
285285
// groups were throwing off the function, causing it to
@@ -288,7 +288,7 @@ public void testNamedGroupsDoesNotThrowIndexOutOfBounds() {
288288
Pattern p = Pattern.compile("(a)(?<foo>b)(?:c)(?<bar>d(?<named>x))");
289289
Matcher m = p.matcher("abcdx");
290290
try {
291-
m.namedGroups();
291+
m.namedGroupsList();
292292
// verified here: IndexOutOfBoundsException did not occur
293293
} catch (IndexOutOfBoundsException e) {
294294
fail("IndexOutOfBoundsException should have been fixed");
@@ -300,7 +300,7 @@ public void testNamedGroupsGetsOnlyNamedGroups() {
300300
Pattern p = Pattern.compile("(a)(?<foo>b)(?:c)(?<bar>d(?<named>x))");
301301
Matcher m = p.matcher("abcdxyz");
302302

303-
List<Map<String, String>> list = m.namedGroups();
303+
List<Map<String, String>> list = m.namedGroupsList();
304304
assertEquals(1, list.size());
305305

306306
Map<String, String> map = list.get(0);
@@ -315,7 +315,7 @@ public void testNamedGroupsWithNoMatchGetsEmptyMap() {
315315
Pattern p = Pattern.compile("(a)(?<foo>b)(?:c)(?<bar>d(?<named>x))");
316316
Matcher m = p.matcher("nada");
317317

318-
List<Map<String, String>> list = m.namedGroups();
318+
List<Map<String, String>> list = m.namedGroupsList();
319319
assertEquals(0, list.size());
320320
}
321321

@@ -757,7 +757,7 @@ public void testNamedGroupsGetsAllMatchesInSingleGroup() {
757757
Pattern pattern = Pattern.compile("(?<digit>\\d)(\\w)");
758758
Matcher matcher = pattern.matcher("2foo3bar4");
759759

760-
final List<Map<String, String>> groups = matcher.namedGroups();
760+
final List<Map<String, String>> groups = matcher.namedGroupsList();
761761
assertEquals(2, groups.size());
762762
assertEquals("2", groups.get(0).get("digit"));
763763
assertEquals("3", groups.get(1).get("digit"));
@@ -768,7 +768,7 @@ public void testNamedGroupsGetsAllMatchesInMultipleGroups() {
768768
Pattern pattern = Pattern.compile("(?<dayOfYear>\\d+).(?<dayName>\\w+)");
769769
Matcher matcher = pattern.matcher("1 Sunday foo bar 2 Monday foo bar 3 Tuesday foo bar 4 Wednesday foo bar 5 Thursday foo bar 6 Friday foo bar 7 Saturday foo bar 8 Sunday foo bar 9 Monday foo bar 10 Tuesday foo bar ");
770770

771-
final List<Map<String, String>> groups = matcher.namedGroups();
771+
final List<Map<String, String>> groups = matcher.namedGroupsList();
772772
final String[] DAYS = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday", "Monday", "Tuesday"};
773773
assertEquals(DAYS.length, groups.size());
774774

@@ -784,15 +784,15 @@ public void testNamedGroupsReturnsEmptyListWhenNoGroupPresent() {
784784
Pattern pattern = Pattern.compile("\\d+ no groups");
785785
Matcher matcher = pattern.matcher("123 no groups");
786786

787-
final List<Map<String, String>> groups = matcher.namedGroups();
787+
final List<Map<String, String>> groups = matcher.namedGroupsList();
788788
assertTrue(groups.isEmpty());
789789
}
790790

791791
// Specify 1 second timeout to account for potential infinite loop (Issue #16)
792792
@Test(timeout=1000)
793793
public void testNamedGroupsReturnsWhenMatchesEmptyString() {
794794
com.google.code.regexp.Matcher matcher = com.google.code.regexp.Pattern.compile("(?<foo>.*)").matcher("bar");
795-
final List<Map<String, String>> groups = matcher.namedGroups();
795+
final List<Map<String, String>> groups = matcher.namedGroupsList();
796796
assertEquals(1, groups.size());
797797
assertEquals("bar", groups.get(0).get("foo"));
798798
}
@@ -804,11 +804,22 @@ public void testNamedGroupsCanBeCalledMultipleTimes() {
804804
final String url = "/teamDrawer/12345";
805805

806806
final Matcher matcher = Pattern.compile(regex).matcher(url);
807-
final Integer count = matcher.namedGroups().size();
807+
final Integer count = matcher.namedGroupsList().size();
808808
assertEquals(Integer.valueOf(1), count);
809-
final Integer mapCount = matcher.namedGroups().get(0).size();
809+
final Integer mapCount = matcher.namedGroupsList().get(0).size();
810810
assertEquals(Integer.valueOf(1), mapCount);
811-
final String value = matcher.namedGroups().get(0).get("roomId");
811+
final String value = matcher.namedGroupsList().get(0).get("roomId");
812812
assertEquals("12345", value);
813813
}
814+
815+
@Test
816+
public void testMatcherNamedGroupsGetsMapsOfGroupIndexes() {
817+
// Test compatibility with MatchResult#namedGroups added in JDK20
818+
// https://github.com/tony19/named-regexp/issues/73
819+
Pattern p = Pattern.compile("(b)(c)(?<named1>x)(d)(?<named2>y)");
820+
MatchResult m = p.matcher("abcxdy");
821+
Map<String, Integer> groupIndexes = m.namedGroups();
822+
assertEquals(Integer.valueOf(3), groupIndexes.get("named1"));
823+
assertEquals(Integer.valueOf(5), groupIndexes.get("named2"));
824+
}
814825
}

0 commit comments

Comments
 (0)