diff --git a/hutool-core/src/main/java/cn/hutool/core/util/ReUtil.java b/hutool-core/src/main/java/cn/hutool/core/util/ReUtil.java index fcad035a5..a5f28313c 100644 --- a/hutool-core/src/main/java/cn/hutool/core/util/ReUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/util/ReUtil.java @@ -9,10 +9,15 @@ import cn.hutool.core.lang.RegexPool; import cn.hutool.core.lang.Validator; import cn.hutool.core.lang.func.Func1; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collection; +import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Map; +import java.util.Map.Entry; import java.util.Set; import java.util.TreeSet; import java.util.regex.MatchResult; @@ -83,6 +88,58 @@ public class ReUtil { return get(pattern, content, groupIndex); } + /** + * 获得匹配的字符串 + * + * @param regex 匹配的正则 + * @param content 被匹配的内容 + * @param groupName 匹配正则的分组名称 + * @return 匹配后得到的字符串,未匹配返回null + */ + public static String getByGroupName(String regex, CharSequence content, String groupName) { + if (null == content || null == regex || null == groupName) { + return null; + } + final Pattern pattern = PatternPool.get(regex, Pattern.DOTALL); + Matcher m = pattern.matcher(content); + if (m.find()) { + return m.group(groupName); + } + return null; + } + + /** + * 获得匹配的字符串 + * + * @param regex 匹配的正则 + * @param content 被匹配的内容 + * @return 命名捕获组 + */ + @SuppressWarnings("unchecked") + public static Map getAllGroupNames(String regex, CharSequence content) { + if (null == content || null == regex) { + return null; + } + Map result = new HashMap<>(); + try { + final Pattern pattern = PatternPool.get(regex, Pattern.DOTALL); + Matcher m = pattern.matcher(content); + // 通过反射获取 namedGroups 方法 + Method method = ReflectUtil.getMethod(Pattern.class, "namedGroups"); + ReflectUtil.setAccessible(method); + Map map = (Map) method.invoke(pattern); + // 组合返回值 + if (m.matches()) { + for (Entry e : map.entrySet()) { + result.put(e.getKey(), m.group(e.getValue())); + } + } + return result; + } catch (InvocationTargetException | IllegalAccessException ex) { + throw new UtilException("call getAllGroupNames(...) method error: " + ex.getMessage()); + } + } + /** * 获得匹配的字符串,,获得正则中分组0的内容 * diff --git a/hutool-core/src/test/java/cn/hutool/core/util/ReUtilTest.java b/hutool-core/src/test/java/cn/hutool/core/util/ReUtilTest.java index 4c392edc0..583274fd8 100644 --- a/hutool-core/src/test/java/cn/hutool/core/util/ReUtilTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/util/ReUtilTest.java @@ -8,6 +8,7 @@ import org.junit.Test; import java.util.ArrayList; import java.util.List; +import java.util.Map; import java.util.regex.Pattern; public class ReUtilTest { @@ -163,4 +164,26 @@ public class ReUtilTest { "(.+?)省(.+?)市(.+?)区", "广东省深圳市南山区"); Console.log(match); } + + @Test + public void getByGroupNameTest() { + String content = "2021-10-11"; + String regex = "(?\\d+)-(?\\d+)-(?\\d+)"; + String year = ReUtil.getByGroupName(regex, content, "year"); + Assert.assertEquals("2021", year); + String month = ReUtil.getByGroupName(regex, content, "month"); + Assert.assertEquals("10", month); + String day = ReUtil.getByGroupName(regex, content, "day"); + Assert.assertEquals("11", day); + } + + @Test + public void getAllGroupNamesTest() { + String content = "2021-10-11"; + String regex = "(?\\d+)-(?\\d+)-(?\\d+)"; + Map map = ReUtil.getAllGroupNames(regex, content); + Assert.assertEquals(map.get("year"), "2021"); + Assert.assertEquals(map.get("month"), "10"); + Assert.assertEquals(map.get("day"), "11"); + } }