Java按指定规则截断字符串:现有代码的异常问题修复
请使用Markdown格式排版以下内容
- 标题类内容使用井号(#)开头
- 列表类内容使用短横线(-)开头
- 文本强调效果使用星号(*)包裹目标内容
- 代码、命令类内容使用反引号(`)包裹目标内容
- 引用类内容使用大于号(>)开头
- 链接格式为:将显示文本放在方括号
[]内,后跟圆括号()包裹的URL地址 - 图片格式为:将图片替代文本放在方括号
[]内,后跟圆括号()包裹的图片资源URL
代码异常原因定位
- 连续分隔符处理缺陷:原代码仅定位截取段内最后一个出现的分隔符位置,未处理相邻多个连续分隔符的场景。当遇到
", "这类连续分隔符时,截断操作会把前一个分隔符(比如逗号)保留在最终结果中,出现text,...这类不符合预期的内容。 - 长入参测试失败的本质:和连续分隔符问题同源。比如测试用例中的原文本
"I want to truncate text, Test",最后一个分隔符是逗号紧跟的空格,原代码定位到空格位置就直接截断,把前面的逗号留在结果里,最终生成"I want to truncate text,...",和测试期望的"I want to truncate text..."不一致。 - 位置判断误差放大:原代码提前对截取段做
trim()操作,会把末尾的分隔符提前移除,导致分隔符定位位置偏移,进一步扩大判断误差。
可正常运行的实现方案
修正后的代码移除了提前trim的操作,增加了连续分隔符回溯逻辑,不依赖第三方工具库,可覆盖所有测试场景:
// 定义规则要求的所有合法分隔符 private static final Set<Character> SEPARATORS = Set.of( ' ', '.', ',', ';', ':', '-', '。', '、', ':', ',', ';' ); public String getTruncateText(String text, int count) { // 空场景兜底 if (text == null || text.isEmpty() || count <= 0) { return "..."; } int textLength = text.length(); // 截取不超过指定长度的初始片段,不做trim避免位置偏移 int takeLength = Math.min(count, textLength); String initialSegment = text.substring(0, takeLength); // 逆向查找初始片段内最后一个分隔符的位置 int lastSepPos = -1; for (int i = initialSegment.length() - 1; i >= 0; i--) { if (SEPARATORS.contains(initialSegment.charAt(i))) { lastSepPos = i; break; } } // 片段内无任何分隔符,直接返回片段加... if (lastSepPos == -1) { return initialSegment + "..."; } // 从最后一个分隔符位置向前回溯,跳过所有连续分隔符,定位真实截断点 int cutPos = lastSepPos; while (cutPos > 0 && SEPARATORS.contains(initialSegment.charAt(cutPos - 1))) { cutPos--; } // 截取到真实截断点,替换为... return initialSegment.substring(0, cutPos) + "..."; }
测试用例校验
所有原有测试场景均可通过验证:
- count=15:返回
I want to...,符合预期 - count=25:返回
I want to truncate text...,符合预期 - count=1:返回
I...,符合预期 - count=2:返回
I...,符合预期 - count=300:返回
I want to truncate text...,不再触发失败 - 连续分隔符场景(如
", "、"; "):自动跳过连续分隔符,不会将分隔符残留在结果中
内容的提问来源于stack exchange,提问作者Aravindan Venkatesan
相关产品推荐
相关产品推荐

