From 2a164a769272404b4b6fc7c9eb30e73cf43c00f4 Mon Sep 17 00:00:00 2001 From: Looly Date: Tue, 12 Dec 2023 04:29:27 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8DStrSplitter.splitByRegex?= =?UTF-8?q?=E4=BD=BF=E7=94=A8=E7=A9=BA=E5=8F=82=E6=95=B0=E5=AF=BC=E8=87=B4?= =?UTF-8?q?=E7=9A=84OOM=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/text/finder/PatternFinder.java | 11 +++++- .../hutool/core/text/split/SplitUtil.java | 38 ++++++++++++------- .../hutool/core/text/split/SplitUtilTest.java | 18 ++++++++- 3 files changed, 51 insertions(+), 16 deletions(-) diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/text/finder/PatternFinder.java b/hutool-core/src/main/java/org/dromara/hutool/core/text/finder/PatternFinder.java index 3c8b766b0..242b42875 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/text/finder/PatternFinder.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/text/finder/PatternFinder.java @@ -63,9 +63,16 @@ public class PatternFinder extends TextFinder { @Override public int start(final int from) { if (matcher.find(from)) { + final int end = matcher.end(); // 只有匹配到的字符串结尾在limit范围内,才算找到 - if(matcher.end() <= getValidEndIndex()){ - return matcher.start(); + if(end <= getValidEndIndex()){ + final int start = matcher.start(); + if(start == end){ + // issue#3421,如果匹配空串,按照未匹配对待,避免死循环 + return INDEX_NOT_FOUND; + } + + return start; } } return INDEX_NOT_FOUND; diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/text/split/SplitUtil.java b/hutool-core/src/main/java/org/dromara/hutool/core/text/split/SplitUtil.java index 97aa1343f..1e613d9f7 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/text/split/SplitUtil.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/text/split/SplitUtil.java @@ -258,7 +258,12 @@ public class SplitUtil { } /** - * 通过正则切分字符串 + * 通过正则切分字符串,规则如下: + * * * @param str 字符串 * @param separatorRegex 分隔符正则 @@ -269,19 +274,19 @@ public class SplitUtil { * @since 3.0.8 */ public static List splitByRegex(final CharSequence str, final String separatorRegex, final int limit, final boolean isTrim, final boolean ignoreEmpty) { - if (StrUtil.isEmpty(str)) { - return ListUtil.zero(); - } - if(StrUtil.isEmpty(separatorRegex)){ - return ListUtil.of(str.toString()); - } - final Pattern pattern = PatternPool.get(separatorRegex); - return splitByRegex(str, pattern, limit, isTrim, ignoreEmpty); + return splitByRegex(str, + // 给定字符串或正则为empty,就不再需要解析pattern + (StrUtil.isEmpty(str) || StrUtil.isEmpty(separatorRegex)) ? null : PatternPool.get(separatorRegex), + limit, isTrim, ignoreEmpty); } /** - * 通过正则切分字符串
- * 如果为空字符串或者null 则返回空集合 + * 通过正则切分字符串,规则如下: + * * * @param str 字符串 * @param separatorPattern 分隔符正则{@link Pattern} @@ -292,11 +297,18 @@ public class SplitUtil { * @since 3.0.8 */ public static List splitByRegex(final CharSequence str, final Pattern separatorPattern, final int limit, final boolean isTrim, final boolean ignoreEmpty) { - if (StrUtil.isEmpty(str)) { + if (null == str) { return ListUtil.zero(); } + if(0 == str.length()){ + return ignoreEmpty ? ListUtil.zero() : ListUtil.of(StrUtil.EMPTY); + } if(null == separatorPattern){ - return ListUtil.of(str.toString()); + final String result = str.toString(); + if(StrUtil.isEmpty(result)){ + return ignoreEmpty ? ListUtil.zero() : ListUtil.of(StrUtil.EMPTY); + } + return ListUtil.of(result); } final SplitIter splitIter = new SplitIter(str, new PatternFinder(separatorPattern), limit, ignoreEmpty); return splitIter.toList(isTrim); diff --git a/hutool-core/src/test/java/org/dromara/hutool/core/text/split/SplitUtilTest.java b/hutool-core/src/test/java/org/dromara/hutool/core/text/split/SplitUtilTest.java index 9781da7b5..c9ae56acd 100644 --- a/hutool-core/src/test/java/org/dromara/hutool/core/text/split/SplitUtilTest.java +++ b/hutool-core/src/test/java/org/dromara/hutool/core/text/split/SplitUtilTest.java @@ -14,10 +14,12 @@ package org.dromara.hutool.core.text.split; import org.dromara.hutool.core.collection.ListUtil; import org.dromara.hutool.core.lang.Console; +import org.dromara.hutool.core.text.finder.PatternFinder; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import java.util.List; +import java.util.regex.Pattern; /** * {@link SplitUtil} 单元测试 @@ -120,9 +122,23 @@ public class SplitUtilTest { @Test void issue3421Test() { List strings = SplitUtil.splitByRegex("", "", 0, false, false); - Assertions.assertEquals(ListUtil.empty(), strings); + Assertions.assertEquals(ListUtil.of(""), strings); strings = SplitUtil.splitByRegex("aaa", "", 0, false, false); Assertions.assertEquals(ListUtil.of("aaa"), strings); + + strings = SplitUtil.splitByRegex("", "aaa", 0, false, false); + Assertions.assertEquals(ListUtil.of(""), strings); + + strings = SplitUtil.splitByRegex("", "", 0, false, true); + Assertions.assertEquals(ListUtil.of(), strings); + } + + @Test + void issue3421Test2() { + // 测试在无前置判断时,是否死循环 + final SplitIter splitIter = new SplitIter("", new PatternFinder(Pattern.compile("")), -1, false); + final List list = splitIter.toList(false); + Assertions.assertEquals(ListUtil.of(""), list); } }