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 {
}
/**
- * 通过正则切分字符串
+ * 通过正则切分字符串,规则如下:
+ *
+ * - 当提供的str为{@code null}时,返回new ArrayList(0)
+ * - 当提供的str为{@code ""}时,返回[""]
+ * - 当提供的separatorRegex为empty(null or "")时,返回[str],即只有原串一个元素的数组
+ *
*
* @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 则返回空集合
+ * 通过正则切分字符串,规则如下:
+ *
+ * - 当提供的str为{@code null}时,返回new ArrayList(0)
+ * - 当提供的str为{@code ""}时,返回[""]
+ * - 当提供的separatorRegex为empty(null or "")时,返回[str],即只有原串一个元素的数组
+ *
*
* @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);
}
}