From db42db25da9e8a1b2eb2b8cb5fa77336f43422ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=A7=E7=81=AByzs?= <835476090@qq.com> Date: Tue, 4 May 2021 14:55:39 +0800 Subject: [PATCH 1/7] =?UTF-8?q?ReUtil=E7=B1=BB=E6=B7=BB=E5=8A=A0delLast?= =?UTF-8?q?=E6=96=B9=E6=B3=95=E2=9C=92=EF=B8=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/cn/hutool/core/util/ReUtil.java | 42 ++++++++++++++- .../java/cn/hutool/core/util/ReUtilTest.java | 54 ++++++++++++++----- 2 files changed, 81 insertions(+), 15 deletions(-) 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 15395d3fc..5cb590fce 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 @@ -299,6 +299,46 @@ public class ReUtil { return pattern.matcher(content).replaceFirst(StrUtil.EMPTY); } + /** + * 删除匹配的最后一个内容 + * + * @param regex 正则 + * @param str 被匹配的内容 + * @return 删除后剩余的内容 + * @since 5.6.5 + */ + public static String delLast(String regex, CharSequence str) { + if (StrUtil.hasBlank(regex, str)) { + return StrUtil.str(str); + } + + final Pattern pattern = PatternPool.get(regex, Pattern.DOTALL); + return delLast(pattern, str); + } + + /** + * 删除匹配的最后一个内容 + * + * @param pattern 正则 + * @param str 被匹配的内容 + * @return 删除后剩余的内容 + * @since 5.6.5 + */ + public static String delLast(Pattern pattern, CharSequence str) { + if (null != pattern && StrUtil.isNotBlank(str)) { + String last = ""; + for (Matcher matcher = pattern.matcher(str); matcher.find(); ) { + last = matcher.group(); + } + + if (StrUtil.isNotBlank(last)){ + return StrUtil.subBefore(str, last, Boolean.TRUE) + StrUtil.subAfter(str, last, Boolean.TRUE); + } + } + + return StrUtil.str(str); + } + /** * 删除匹配的全部内容 * @@ -724,4 +764,4 @@ public class ReUtil { } return builder.toString(); } -} \ No newline at end of file +} 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 d7efe1626..6f07e1452 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 @@ -1,6 +1,7 @@ package cn.hutool.core.util; import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.lang.PatternPool; import org.junit.Assert; import org.junit.Test; @@ -23,7 +24,7 @@ public class ReUtilTest { String resultExtractMulti = ReUtil.extractMulti("(\\w)aa(\\w)", content, "$1-$2"); Assert.assertEquals("Z-a", resultExtractMulti); } - + @Test public void extractMultiTest2() { // 抽取多个分组然后把它们拼接起来 @@ -37,7 +38,32 @@ public class ReUtilTest { String resultDelFirst = ReUtil.delFirst("(\\w)aa(\\w)", content); Assert.assertEquals("ZZbbbccc中文1234", resultDelFirst); } - + + @Test + public void delLastTest(){ + String blank = ""; + String word = "180公斤"; + String sentence = "10.商品KLS100021型号xxl适合身高180体重130斤的用户"; + //空字符串兼容 + Assert.assertEquals(blank,ReUtil.delLast("\\d+", blank)); + Assert.assertEquals(blank,ReUtil.delLast(PatternPool.NUMBERS, blank)); + + //去除数字 + Assert.assertEquals("公斤",ReUtil.delLast("\\d+", word)); + Assert.assertEquals("公斤",ReUtil.delLast(PatternPool.NUMBERS, word)); + //去除汉字 + Assert.assertEquals("180",ReUtil.delLast("[\u4E00-\u9FFF]+", word)); + Assert.assertEquals("180",ReUtil.delLast(PatternPool.CHINESES, word)); + + //多个匹配删除最后一个 判断是否不在包含最后的数字 + Assert.assertFalse(ReUtil.delLast("\\d+", sentence).contains("130")); + Assert.assertFalse(ReUtil.delLast(PatternPool.NUMBERS, sentence).contains("130")); + + //多个匹配删除最后一个 判断是否不在包含最后的数字 + Assert.assertFalse(ReUtil.delLast("[\u4E00-\u9FFF]+", sentence).contains("斤的用户")); + Assert.assertFalse(ReUtil.delLast(PatternPool.CHINESES, sentence).contains("斤的用户")); + } + @Test public void delAllTest() { // 删除所有匹配到的内容 @@ -60,14 +86,14 @@ public class ReUtilTest { Integer resultGetFirstNumber = ReUtil.getFirstNumber(content); Assert.assertEquals(Integer.valueOf(1234), resultGetFirstNumber); } - + @Test public void isMatchTest() { // 给定字符串是否匹配给定正则 boolean isMatch = ReUtil.isMatch("\\w+[\u4E00-\u9FFF]+\\d+", content); Assert.assertTrue(isMatch); } - + @Test public void replaceAllTest() { //通过正则查找到字符串,然后把匹配到的字符串加入到replacementTemplate中,$1表示分组1的字符串 @@ -75,43 +101,43 @@ public class ReUtilTest { String replaceAll = ReUtil.replaceAll(content, "(\\d+)", "->$1<-"); Assert.assertEquals("ZZZaaabbbccc中文->1234<-", replaceAll); } - + @Test public void replaceAllTest2() { //此处把1234替换为 ->1234<- String replaceAll = ReUtil.replaceAll(this.content, "(\\d+)", parameters -> "->" + parameters.group(1) + "<-"); Assert.assertEquals("ZZZaaabbbccc中文->1234<-", replaceAll); } - + @Test public void replaceTest() { String str = "AAABBCCCBBDDDBB"; String replace = StrUtil.replace(str, 0, "BB", "22", false); Assert.assertEquals("AAA22CCC22DDD22", replace); - + replace = StrUtil.replace(str, 3, "BB", "22", false); Assert.assertEquals("AAA22CCC22DDD22", replace); - + replace = StrUtil.replace(str, 4, "BB", "22", false); Assert.assertEquals("AAABBCCC22DDD22", replace); - + replace = StrUtil.replace(str, 4, "bb", "22", true); Assert.assertEquals("AAABBCCC22DDD22", replace); - + replace = StrUtil.replace(str, 4, "bb", "", true); Assert.assertEquals("AAABBCCCDDD", replace); - + replace = StrUtil.replace(str, 4, "bb", null, true); Assert.assertEquals("AAABBCCCDDD", replace); } - + @Test public void escapeTest() { //转义给定字符串,为正则相关的特殊符号转义 String escape = ReUtil.escape("我有个$符号{}"); Assert.assertEquals("我有个\\$符号\\{\\}", escape); } - + @Test public void getAllGroupsTest() { //转义给定字符串,为正则相关的特殊符号转义 @@ -121,7 +147,7 @@ public class ReUtilTest { Assert.assertEquals("192", allGroups.get(1)); Assert.assertEquals("168", allGroups.get(2)); Assert.assertEquals("1", allGroups.get(3)); - + allGroups = ReUtil.getAllGroups(pattern, "192-168-1-1", false); Assert.assertEquals("192", allGroups.get(0)); Assert.assertEquals("168", allGroups.get(1)); From 788537d9f06f8c914cf9ecb5126de6826bf350fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=A7=E7=81=AByzs?= <835476090@qq.com> Date: Tue, 4 May 2021 14:59:05 +0800 Subject: [PATCH 2/7] =?UTF-8?q?Validator=E7=B1=BB=E6=B7=BB=E5=8A=A0hasNumb?= =?UTF-8?q?er=E6=96=B9=E6=B3=95=E2=9C=92=EF=B8=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/cn/hutool/core/lang/Validator.java | 11 +++++++++++ .../test/java/cn/hutool/core/lang/ValidatorTest.java | 12 ++++++++++++ 2 files changed, 23 insertions(+) diff --git a/hutool-core/src/main/java/cn/hutool/core/lang/Validator.java b/hutool-core/src/main/java/cn/hutool/core/lang/Validator.java index cde7cb4ab..e71f2d594 100644 --- a/hutool-core/src/main/java/cn/hutool/core/lang/Validator.java +++ b/hutool-core/src/main/java/cn/hutool/core/lang/Validator.java @@ -586,6 +586,17 @@ public class Validator { return NumberUtil.isNumber(value); } + /** + * 是否包含数字 + * + * @param value 当前字符串 + * @return boolean 是否存在数字 + * @since 5.6.5 + */ + public static boolean hasNumber(CharSequence value) { + return ReUtil.contains(PatternPool.NUMBERS, value); + } + /** * 验证是否为数字 * diff --git a/hutool-core/src/test/java/cn/hutool/core/lang/ValidatorTest.java b/hutool-core/src/test/java/cn/hutool/core/lang/ValidatorTest.java index 4a2af9d81..a14a3d8dd 100644 --- a/hutool-core/src/test/java/cn/hutool/core/lang/ValidatorTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/lang/ValidatorTest.java @@ -20,6 +20,18 @@ public class ValidatorTest { Assert.assertTrue(Validator.isNumber("0.33323")); } + @Test + public void hasNumberTest() throws Exception { + String var1 = ""; + String var2 = "str"; + String var3 = "180"; + String var4 = "身高180体重180"; + Assert.assertFalse(Validator.hasNumber(var1)); + Assert.assertFalse(Validator.hasNumber(var2)); + Assert.assertTrue(Validator.hasNumber(var3)); + Assert.assertTrue(Validator.hasNumber(var4)); + } + @Test public void isLetterTest() { Assert.assertTrue(Validator.isLetter("asfdsdsfds")); From 32e29438d7be0d0279443f9cdfc643aaaa46a216 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=A7=E7=81=AByzs?= <835476090@qq.com> Date: Tue, 4 May 2021 15:00:49 +0800 Subject: [PATCH 3/7] =?UTF-8?q?NumberUtil=E7=B1=BB=E6=B7=BB=E5=8A=A0percen?= =?UTF-8?q?t=E6=96=B9=E6=B3=95=E2=9C=92=EF=B8=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/cn/hutool/core/util/NumberUtil.java | 25 +++++++++++++++++++ .../cn/hutool/core/util/NumberUtilTest.java | 10 ++++++++ 2 files changed, 35 insertions(+) diff --git a/hutool-core/src/main/java/cn/hutool/core/util/NumberUtil.java b/hutool-core/src/main/java/cn/hutool/core/util/NumberUtil.java index 392e4ce63..644d5c154 100644 --- a/hutool-core/src/main/java/cn/hutool/core/util/NumberUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/util/NumberUtil.java @@ -765,6 +765,18 @@ public class NumberUtil { return (int) Math.ceil((double) v1 / v2); } + /** + * 求百分比(取整) (3,10) => 30 + * + * @param num 当前num + * @param total 总长度 + * @return int 百分比(取整) + * @since 5.6.5 + */ + public static int percent(int num, int total) { + return (int) ((float) num / (float) total * 100); + } + // ------------------------------------------------------------------------------------------- round /** @@ -1082,6 +1094,19 @@ public class NumberUtil { return format.format(number); } + /** + * 求百分比(带精度)(带百分号后缀) (3,10,0) => 30% + * + * @param num 当前num + * @param total 总长度 + * @param scale 精度(保留小数点后几位) + * @return String 百分比(带百分号后缀) + * @since 5.6.5 + */ + public static String formatPercent(Number num, Number total, int scale) { + return formatPercent(num.doubleValue() / total.doubleValue(), scale); + } + // ------------------------------------------------------------------------------------------- isXXX /** diff --git a/hutool-core/src/test/java/cn/hutool/core/util/NumberUtilTest.java b/hutool-core/src/test/java/cn/hutool/core/util/NumberUtilTest.java index 7a7e437f3..838dc79b9 100644 --- a/hutool-core/src/test/java/cn/hutool/core/util/NumberUtilTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/util/NumberUtilTest.java @@ -178,10 +178,20 @@ public class NumberUtilTest { Assert.assertTrue(NumberUtil.equals(new BigDecimal("0.00"), BigDecimal.ZERO)); } + @Test + public void percentTest(){ + Assert.assertEquals(30, NumberUtil.percent(3, 10)); + Assert.assertEquals(20, NumberUtil.percent(1, 5)); + } + @Test public void formatPercentTest() { String str = NumberUtil.formatPercent(0.33543545, 2); Assert.assertEquals("33.54%", str); + + Assert.assertEquals("30%", NumberUtil.formatPercent(3, 10, 0)); + Assert.assertEquals("33.33%", NumberUtil.formatPercent(1, 3, 2)); + Assert.assertEquals("33.333%", NumberUtil.formatPercent(1, 3, 3)); } @Test From a1dba4f36bb85e6f0eb49a2a9835c5f84845f603 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=A7=E7=81=AByzs?= <835476090@qq.com> Date: Tue, 4 May 2021 15:01:43 +0800 Subject: [PATCH 4/7] =?UTF-8?q?ListUtil=E7=B1=BB=E6=B7=BB=E5=8A=A0countMap?= =?UTF-8?q?=E6=96=B9=E6=B3=95=E2=9C=92=EF=B8=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cn/hutool/core/collection/ListUtil.java | 37 +++++++++++++++---- .../hutool/core/collection/ListUtilTest.java | 22 +++++++++++ 2 files changed, 51 insertions(+), 8 deletions(-) diff --git a/hutool-core/src/main/java/cn/hutool/core/collection/ListUtil.java b/hutool-core/src/main/java/cn/hutool/core/collection/ListUtil.java index 088e19787..d6a3093d2 100644 --- a/hutool-core/src/main/java/cn/hutool/core/collection/ListUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/collection/ListUtil.java @@ -5,18 +5,12 @@ import cn.hutool.core.comparator.PropertyComparator; import cn.hutool.core.convert.Convert; import cn.hutool.core.lang.Editor; import cn.hutool.core.lang.Matcher; +import cn.hutool.core.map.MapUtil; import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.PageUtil; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; -import java.util.Enumeration; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; +import java.util.*; import java.util.concurrent.CopyOnWriteArrayList; public class ListUtil { @@ -450,6 +444,33 @@ public class ListUtil { return list2; } + /** + * 统计list中元素出现次数 + * + * @param list list容器 + * @return Map 统计次数 如: {"hello":10} + * @since 5.6.5 + */ + public static Map countMap(List list) { + Map countMap = MapUtil.newHashMap(); + for (T o : list) { + countMap.put(o, countMap.getOrDefault(o, 0L) + 1); + } + return countMap; + //return list.stream().collect(Collectors.groupingBy(o -> o, Collectors.counting()));//stream方式 + } + + /** + * 统计list中元素出现次数 + * + * @param list list容器 + * @return Map 统计次数 如: {"hello":10} + * @since 5.6.5 + */ + public static Map countMap(List list, boolean isValueDesc) { + return MapUtil.sortByValue(countMap(list), isValueDesc); + } + /** * 获取匹配规则定义中匹配到元素的所有位置 * diff --git a/hutool-core/src/test/java/cn/hutool/core/collection/ListUtilTest.java b/hutool-core/src/test/java/cn/hutool/core/collection/ListUtilTest.java index 46c94cdd5..17f413a0a 100644 --- a/hutool-core/src/test/java/cn/hutool/core/collection/ListUtilTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/collection/ListUtilTest.java @@ -10,6 +10,7 @@ import org.junit.Test; import java.util.ArrayList; import java.util.List; +import java.util.Map; public class ListUtilTest { @@ -46,6 +47,27 @@ public class ListUtilTest { Assert.assertEquals("edit3", filter.get(2)); } + @Test + @Ignore + public void countMapTest(){ + List list = new ArrayList<>(); + list.add("AAA"); + list.add("BBB"); + list.add("AAA"); + list.add("CCC"); + list.add("DDD"); + list.add("DDD"); + //统计不排序 + Map countMap = ListUtil.countMap(list); + Console.log(countMap); + //统计倒序排列 + Map descCountMap = ListUtil.countMap(list, Boolean.TRUE); + Console.log(descCountMap); + //统计正序排列 + Map ascCountMap= ListUtil.countMap(list, Boolean.FALSE); + Console.log(ascCountMap); + } + @Test public void indexOfAll() { List a = ListUtil.toLinkedList("1", "2", "3", "4", "3", "2", "1"); From bc9ef1994bc5b56eebdb30cac8579b99aa42b093 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=A7=E7=81=AByzs?= <835476090@qq.com> Date: Tue, 4 May 2021 15:03:02 +0800 Subject: [PATCH 5/7] =?UTF-8?q?StrUtil=E7=B1=BB=E6=B7=BB=E5=8A=A0wordCount?= =?UTF-8?q?=E6=96=B9=E6=B3=95=E2=9C=92=EF=B8=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/cn/hutool/core/util/StrUtil.java | 62 +++++++++++++++++++ .../java/cn/hutool/core/util/StrUtilTest.java | 19 ++++++ 2 files changed, 81 insertions(+) diff --git a/hutool-core/src/main/java/cn/hutool/core/util/StrUtil.java b/hutool-core/src/main/java/cn/hutool/core/util/StrUtil.java index f01ac7601..1081eccbc 100644 --- a/hutool-core/src/main/java/cn/hutool/core/util/StrUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/util/StrUtil.java @@ -1,5 +1,6 @@ package cn.hutool.core.util; +import cn.hutool.core.map.MapUtil; import cn.hutool.core.text.CharSequenceUtil; import cn.hutool.core.text.StrBuilder; import cn.hutool.core.text.StrPool; @@ -9,6 +10,8 @@ import java.io.StringReader; import java.io.StringWriter; import java.nio.ByteBuffer; import java.nio.charset.Charset; +import java.util.Collections; +import java.util.List; import java.util.Map; /** @@ -469,4 +472,63 @@ public class StrUtil extends CharSequenceUtil implements StrPool { } return template2; } + + //------------------------------------------------------------------------ wordCount + + /** + * 统计 字符串 中单词出现次数(不排序) + * + * @param str 字符串 + * @param separator 分隔符 + * @return Map 统计次数 如: {"hello":10} + * @since 5.6.5 + */ + public static Map wordCount(String str, String separator) { + return wordCount(Collections.singletonList(str), separator); + } + + /** + * 统计 字符串 中单词出现次数(根据value排序) + * + * @param str 字符串 + * @param separator 分隔符 + * @param isValueDesc 是否倒叙排列 + * @return Map 统计次数 如: {"hello":10} + * @since 5.6.5 + */ + public static Map wordCount(String str, String separator, boolean isValueDesc) { + return wordCount(Collections.singletonList(str), separator, isValueDesc); + } + + /** + * 统计list中单词出现次数(不排序) + * + * @param list list容器 + * @param separator 分隔符 + * @return Map 统计次数 如: {"hello":10} + * @since 5.6.5 + */ + public static Map wordCount(List list, String separator) { + Map countMap = MapUtil.newHashMap(); + for (String str : list) { + String[] words = str.split(separator); + for (String word : words) { + countMap.put(word, countMap.getOrDefault(word, 0L) + 1); + } + } + return countMap; + } + + /** + * 统计 字符串list 中单词出现次数(根据value排序) + * + * @param list list容器 + * @param separator 分隔符 + * @param isValueDesc 是否根据value倒叙排列 + * @return Map 统计次数 如: {"hello":10} + * @since 5.6.5 + */ + public static Map wordCount(List list, String separator, boolean isValueDesc) { + return MapUtil.sortByValue(wordCount(list, separator), isValueDesc); + } } diff --git a/hutool-core/src/test/java/cn/hutool/core/util/StrUtilTest.java b/hutool-core/src/test/java/cn/hutool/core/util/StrUtilTest.java index 2c028b794..691a6ae2a 100644 --- a/hutool-core/src/test/java/cn/hutool/core/util/StrUtilTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/util/StrUtilTest.java @@ -4,7 +4,9 @@ import cn.hutool.core.lang.Dict; import org.junit.Assert; import org.junit.Test; +import java.util.ArrayList; import java.util.List; +import java.util.Map; /** * 字符串工具类单元测试 @@ -508,4 +510,21 @@ public class StrUtilTest { Assert.assertEquals("jackduan@163.com", StrUtil.hide("jackduan@163.com", 16, 16)); Assert.assertEquals("jackduan@163.com", StrUtil.hide("jackduan@163.com", 16, 17)); } + + @Test + public void wordCountTest(){ + List list = new ArrayList<>(); + list.add("Word Count"); + list.add("Hello world"); + list.add("Hello java"); + list.add("Hello Hutool"); + list.add("A set of tools that keep Java sweet"); + Map listCountMap = StrUtil.wordCount(list, " "); + Assert.assertEquals(3L, listCountMap.get("Hello").longValue()); + + String singleton = "Can you can a can as a canner can can a can ?"; + Map strCountMap = StrUtil.wordCount(singleton, " "); + Assert.assertEquals(5L, strCountMap.get("can").longValue()); + } + } From 442d4bd854cf2875887a6f3e72a0230e71f9ca46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=A7=E7=81=AByzs?= <835476090@qq.com> Date: Tue, 4 May 2021 15:05:23 +0800 Subject: [PATCH 6/7] =?UTF-8?q?CharSequenceUtil=E7=B1=BB=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?startWith,endWith,remove=E6=96=B9=E6=B3=95=E2=9C=92=EF=B8=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cn/hutool/core/text/CharSequenceUtil.java | 111 ++++++++++++++++ .../core/text/CharSequenceUtilTest.java | 123 ++++++++++++++++++ 2 files changed, 234 insertions(+) diff --git a/hutool-core/src/main/java/cn/hutool/core/text/CharSequenceUtil.java b/hutool-core/src/main/java/cn/hutool/core/text/CharSequenceUtil.java index d07b3c408..327c4be4e 100644 --- a/hutool-core/src/main/java/cn/hutool/core/text/CharSequenceUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/text/CharSequenceUtil.java @@ -4,6 +4,7 @@ import cn.hutool.core.comparator.VersionComparator; import cn.hutool.core.convert.Convert; import cn.hutool.core.lang.Assert; import cn.hutool.core.lang.Filter; +import cn.hutool.core.lang.PatternPool; import cn.hutool.core.lang.func.Func1; import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.CharUtil; @@ -765,6 +766,50 @@ public class CharSequenceUtil { return false; } + /** + * 字符串是否以(数字)开始 + * + * @param str 字符串 + * @return 是否数字开始 + * @since 5.6.5 + */ + public static boolean startWithNumber(CharSequence str) { + return isNotBlank(str) && PatternPool.NUMBERS.matcher(str.subSequence(0, 1)).find(); + } + + /** + * 字符串是否以(英文字母 、数字和下划线)开始 + * + * @param str 字符串 + * @return 是否英文字母 、数字和下划线开始 + * @since 5.6.5 + */ + public static boolean startWithGeneral(CharSequence str) { + return isNotBlank(str) && PatternPool.GENERAL.matcher(str.subSequence(0, 1)).find(); + } + + /** + * 字符串是否以(字母)开始 + * + * @param str 字符串 + * @return 是否字母开始 + * @since 5.6.5 + */ + public static boolean startWithWord(CharSequence str) { + return isNotBlank(str) && PatternPool.WORD.matcher(str.subSequence(0, 1)).find(); + } + + /** + * 字符串是否以(中文汉字)开始 + * + * @param str 字符串 + * @return 是否中文汉字开始 + * @since 5.6.5 + */ + public static boolean startWithChinese(CharSequence str) { + return isNotBlank(str) && PatternPool.CHINESES.matcher(str.subSequence(0, 1)).find(); + } + // ------------------------------------------------------------------------ endWith /** @@ -868,6 +913,50 @@ public class CharSequenceUtil { return false; } + /** + * 字符串是否以(数字)结束 + * + * @param str 字符串 + * @return 是否数字结束 + * @since 5.6.5 + */ + public static boolean endWithNumber(CharSequence str) { + return isNotBlank(str) && PatternPool.NUMBERS.matcher(str.subSequence(str.length() - 1, str.length())).find(); + } + + /** + * 字符串是否以(英文字母 、数字和下划线)结束 + * + * @param str 字符串 + * @return 是否英文字母 、数字和下划线结束 + * @since 5.6.5 + */ + public static boolean endWithGeneral(CharSequence str) { + return isNotBlank(str) && PatternPool.GENERAL.matcher(str.subSequence(str.length() - 1, str.length())).find(); + } + + /** + * 字符串是否以(字母)结束 + * + * @param str 字符串 + * @return 是否字母结束 + * @since 5.6.5 + */ + public static boolean endWithWord(CharSequence str) { + return isNotBlank(str) && PatternPool.WORD.matcher(str.subSequence(str.length() - 1, str.length())).find(); + } + + /** + * 字符串是否以(中文汉字)结束 + * + * @param str 字符串 + * @return 是否中文汉字结束 + * @since 5.6.5 + */ + public static boolean endWithChinese(CharSequence str) { + return isNotBlank(str) && PatternPool.CHINESES.matcher(str.subSequence(str.length() - 1, str.length())).find(); + } + // ------------------------------------------------------------------------ contains /** @@ -1505,6 +1594,28 @@ public class CharSequenceUtil { return str2; } + /** + * 剔除/移除字符串中的所有数字 + * + * @param str 当前字符串 + * @return 移除数字后的字符串 + * @since 5.6.5 + */ + public static String removeNumbers(CharSequence str) { + return ReUtil.delAll(PatternPool.NUMBERS, str); + } + + /** + * 剔除/移除字符串中的所有中文 + * + * @param str 当前字符串 + * @return 移除中文后的字符串 + * @since 5.6.5 + */ + public static String removeChinese(CharSequence str) { + return ReUtil.delAll(PatternPool.CHINESES, str); + } + /** * 清理空白字符 * diff --git a/hutool-core/src/test/java/cn/hutool/core/text/CharSequenceUtilTest.java b/hutool-core/src/test/java/cn/hutool/core/text/CharSequenceUtilTest.java index 191e31137..e64bf075b 100644 --- a/hutool-core/src/test/java/cn/hutool/core/text/CharSequenceUtilTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/text/CharSequenceUtilTest.java @@ -24,4 +24,127 @@ public class CharSequenceUtilTest { result = CharSequenceUtil.addSuffixIfNot(str, " is Good"); Assert.assertEquals( str + " is Good", result); } + + @Test + public void startWithNumberTest() throws Exception { + String var1 = "123str"; + String var2 = "180公斤"; + String var3 = "str"; + String var4 = "身高180"; + Assert.assertTrue(CharSequenceUtil.startWithNumber(var1)); + Assert.assertTrue(CharSequenceUtil.startWithNumber(var2)); + Assert.assertFalse(CharSequenceUtil.startWithNumber(var3)); + Assert.assertFalse(CharSequenceUtil.startWithNumber(var4)); + } + + @Test + public void startWithGeneralTest() throws Exception { + String var1 = "str"; + String var2 = "123"; + String var3 = "_str"; + String var4 = "身高180"; + Assert.assertTrue(CharSequenceUtil.startWithGeneral(var1)); + Assert.assertTrue(CharSequenceUtil.startWithGeneral(var2)); + Assert.assertTrue(CharSequenceUtil.startWithGeneral(var3)); + Assert.assertFalse(CharSequenceUtil.startWithGeneral(var4)); + } + + @Test + public void startWithWordTest() throws Exception { + String var1 = "str"; + String var2 = "123"; + String var3 = "_str"; + String var4 = "身高180"; + Assert.assertTrue(CharSequenceUtil.startWithWord(var1)); + Assert.assertFalse(CharSequenceUtil.startWithWord(var2)); + Assert.assertFalse(CharSequenceUtil.startWithWord(var3)); + Assert.assertFalse(CharSequenceUtil.startWithWord(var4)); + } + + @Test + public void startWithChineseTest() throws Exception { + String var1 = "str"; + String var2 = "_str"; + String var3 = "123"; + String var4 = "身高180"; + Assert.assertFalse(CharSequenceUtil.startWithChinese(var1)); + Assert.assertFalse(CharSequenceUtil.startWithChinese(var2)); + Assert.assertFalse(CharSequenceUtil.startWithChinese(var3)); + Assert.assertTrue(CharSequenceUtil.startWithChinese(var4)); + } + + @Test + public void endWithNumberTest() throws Exception { + String var1 = "str123"; + String var2 = "身高180"; + String var3 = "str"; + String var4 = "180公斤"; + Assert.assertTrue(CharSequenceUtil.endWithNumber(var1)); + Assert.assertTrue(CharSequenceUtil.endWithNumber(var2)); + Assert.assertFalse(CharSequenceUtil.endWithNumber(var3)); + Assert.assertFalse(CharSequenceUtil.endWithNumber(var4)); + } + + @Test + public void endWithGeneralTest() throws Exception { + String var1 = "str"; + String var2 = "123"; + String var3 = "str_"; + String var4 = "180公斤"; + Assert.assertTrue(CharSequenceUtil.endWithGeneral(var1)); + Assert.assertTrue(CharSequenceUtil.endWithGeneral(var2)); + Assert.assertTrue(CharSequenceUtil.endWithGeneral(var3)); + Assert.assertFalse(CharSequenceUtil.endWithGeneral(var4)); + } + + @Test + public void endWithWordTest() throws Exception { + String var1 = "str"; + String var2 = "_str"; + String var3 = "123"; + String var4 = "身高180"; + Assert.assertTrue(CharSequenceUtil.endWithWord(var1)); + Assert.assertTrue(CharSequenceUtil.endWithWord(var2)); + Assert.assertFalse(CharSequenceUtil.endWithWord(var3)); + Assert.assertFalse(CharSequenceUtil.endWithWord(var4)); + } + + @Test + public void endWithChineseTest() throws Exception { + String var1 = "str"; + String var2 = "_str"; + String var3 = "123"; + String var4 = "180公斤"; + Assert.assertFalse(CharSequenceUtil.endWithChinese(var1)); + Assert.assertFalse(CharSequenceUtil.endWithChinese(var2)); + Assert.assertFalse(CharSequenceUtil.endWithChinese(var3)); + Assert.assertTrue(CharSequenceUtil.endWithChinese(var4)); + } + + // ------------------------------------------------------------------------ remove + + @Test + public void removeNumbersTest(){ + String var1 = ""; + String var2 = "str"; + String var3 = "身高180"; + String var4 = "身高180体重180"; + Assert.assertEquals("", CharSequenceUtil.removeNumbers(var1)); + Assert.assertEquals("str", CharSequenceUtil.removeNumbers(var2)); + Assert.assertEquals("身高", CharSequenceUtil.removeNumbers(var3)); + Assert.assertEquals("身高体重", CharSequenceUtil.removeNumbers(var4)); + } + + @Test + public void removeChineseTest(){ + String var1 = ""; + String var2 = "str"; + String var3 = "身高180"; + String var4 = "身高180体重180cm"; + Assert.assertEquals("", CharSequenceUtil.removeChinese(var1)); + Assert.assertEquals("str", CharSequenceUtil.removeChinese(var2)); + Assert.assertEquals("180", CharSequenceUtil.removeChinese(var3)); + Assert.assertEquals("180180cm", CharSequenceUtil.removeChinese(var4)); + } + } From ddf384884b267ee592703ba7928756d258a310b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=A7=E7=81=AByzs?= <835476090@qq.com> Date: Sat, 8 May 2021 00:40:17 +0800 Subject: [PATCH 7/7] =?UTF-8?q?fixbug=20WordTree=E8=A6=86=E5=86=99clear?= =?UTF-8?q?=E6=96=B9=E6=B3=95=E2=9C=92=EF=B8=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/cn/hutool/dfa/WordTree.java | 11 ++++++++ .../src/test/java/cn/hutool/dfa/DfaTest.java | 26 ++++++++++++++++++- 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/hutool-dfa/src/main/java/cn/hutool/dfa/WordTree.java b/hutool-dfa/src/main/java/cn/hutool/dfa/WordTree.java index 1f3d75e36..310f5958b 100644 --- a/hutool-dfa/src/main/java/cn/hutool/dfa/WordTree.java +++ b/hutool-dfa/src/main/java/cn/hutool/dfa/WordTree.java @@ -321,5 +321,16 @@ public class WordTree extends HashMap { this.endCharacterSet.add(c); } } + + /** + * 清除所有的词, + * 此方法调用后, wordTree 将被清空 + * endCharacterSet 也将清空 + */ + @Override + public void clear() { + super.clear(); + this.endCharacterSet.clear(); + } //--------------------------------------------------------------------------------------- Private method end } diff --git a/hutool-dfa/src/test/java/cn/hutool/dfa/DfaTest.java b/hutool-dfa/src/test/java/cn/hutool/dfa/DfaTest.java index 680ea2d78..d466f69b7 100644 --- a/hutool-dfa/src/test/java/cn/hutool/dfa/DfaTest.java +++ b/hutool-dfa/src/test/java/cn/hutool/dfa/DfaTest.java @@ -101,6 +101,30 @@ public class DfaTest { Assert.assertEquals("[women]", matchAll.toString()); } + @Test + public void clearTest(){ + WordTree tree = new WordTree(); + tree.addWord("黑"); + Assert.assertTrue(tree.matchAll("黑大衣").contains("黑")); + //clear时直接调用Map的clear并没有把endCharacterSet清理掉 + tree.clear(); + tree.addWords("黑大衣","红色大衣"); + + //clear() 覆写前 这里想匹配到黑大衣,但是却匹配到了黑 +// Assert.assertFalse(tree.matchAll("黑大衣").contains("黑大衣")); +// Assert.assertTrue(tree.matchAll("黑大衣").contains("黑")); + //clear() 覆写后 + Assert.assertTrue(tree.matchAll("黑大衣").contains("黑大衣")); + Assert.assertFalse(tree.matchAll("黑大衣").contains("黑")); + Assert.assertTrue(tree.matchAll("红色大衣").contains("红色大衣")); + + //如果不覆写只能通过new出新对象才不会有问题 + tree = new WordTree(); + tree.addWords("黑大衣","红色大衣"); + Assert.assertTrue(tree.matchAll("黑大衣").contains("黑大衣")); + Assert.assertTrue(tree.matchAll("红色大衣").contains("红色大衣")); + } + // ---------------------------------------------------------------------------------------------------------- /** * 构建查找树 @@ -117,4 +141,4 @@ public class DfaTest { tree.addWord("出锅"); return tree; } -} \ No newline at end of file +}