如何用Java优雅拆分字符串为单词与非单词子串?
更简洁优雅的Java标准库实现方案
嘿,我有个更简洁优雅的实现思路,完全依赖Java标准库就能搞定,逻辑比你当前的写法清晰很多:
我们可以直接用一个正则表达式,同时匹配连续的单词片段和连续的非单词片段,然后通过遍历所有匹配结果来收集拆分后的列表,不需要手动处理索引和边界判断。
import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; public class StringSplitter { // 正则匹配:要么是连续字母(单词),要么是连续非字母(非单词) private static final Pattern WORD_OR_NON_WORD_PATTERN = Pattern.compile("([a-zA-Z]+)|([^a-zA-Z]+)"); public static List<String> splitString(String str) { if (str == null) { return null; } List<String> splitParts = new ArrayList<>(); Matcher matcher = WORD_OR_NON_WORD_PATTERN.matcher(str); while (matcher.find()) { splitParts.add(matcher.group()); } return splitParts; } }
这个方案的优势:
- 逻辑直观:正则直接定义了我们需要捕获的两种片段,不需要跟踪
endOfLastWord这类状态变量,避免了容易出错的边界计算 - 代码精简:去掉了手动截取子串的复杂逻辑,整体结构更清晰易读
- 符合需求:测试你的示例输入
"A! B C, d.",会得到完全符合预期的结果:Arrays.asList("A", "! ", "B", " ", "C", ", ", "d", ".")
如果需要适配更通用的字母(比如Unicode中的其他语言字母),可以把正则里的[a-zA-Z]+换成\p{L}+(匹配任何Unicode字母),对应的非单词部分换成\P{L}+,这样兼容性更强。
内容的提问来源于stack exchange,提问作者lexicore
相关产品推荐
相关产品推荐

