17370845950

如何将 Java 中 ArrayList 的字符串按每两个字符分割为子串

本文介绍如何使用正则表达式将 arraylist 中的每个英文字符串精确拆分为长度为 2 的子串(末尾不足两位时保留原样),适用于奇偶长度统一处理的分词场景。

在自然语言处理或自定义词法分析器(如 Tokenizer 类)中,常需将单词按固定宽度切片。题目要求:对 Reader 类生成的 Wlist(全大写英文单词列表),将每个字符串从左到右每两个字符切分为一个子串,无论原字符串长度是奇数还是偶数——这恰好对应“三段式”视觉分组(如 "teacher" → "te", "ac", "her";"cattle" → "ca", "tt", "le"),其本质是以步长 2 进行等宽切片,末段容纳剩余字符

Java 中最简洁、高效的方式是使用正则表达式的 split() 配合边界断言(lookaround),而非手动计算索引或循环截取。核心正则表达式为:

"(?<=\\G..)(?=..)"
  • \\G 表示上一次匹配结束的位置(或字符串开头);
  • (?正向后查找(positive lookbehind):断言当前位置前恰好有两个字符,且这两个字符紧接在上一匹配之后;
  • (?=..) 是正向前查找(positive lookahead):断言当前位置后至少还有两个字符;
  • 二者组合,即在“每两个字符之后、且后面仍有至少两个字符”的位置进行分割。

⚠️ 注意:该正则不会在末尾产生空字符串,也无需额外处理奇偶逻辑——它天然适配所有长度。例如:

  • "Printer"(7 字符)→ ["Pr", "in", "ter"]
  • "Airport"(7 字符)→ ["Ai", "rp", "ort"]
  • "Letter"(6 字符)→ ["Le", "tt", "er"]

✅ 正确实现 Tokenizer.splitString()

需修正原代码中的两个关键问题:

  1. 错误使用 Arrays.toString(...) 将 String[] 转为 [a, b, c] 格式字符串,导致 SplList 存的是文本而非子串数组;
  2. 未导入 java.util.Arrays,且 split() 应作用于单个字符串,而非整个 ArrayList。

以下是修复后的专业级实现:

import java.util.*;
import java.util.stream.Collect

ors; public class Tokenizer { private final Reader rd = new Reader(); public List> splitString() { List wordList = rd.getWord(); // 获取大写单词列表 List> result = new ArrayList<>(); for (String word : wordList) { String[] parts = word.split("(?<=\\G..)(?=..)"); result.add(Arrays.asList(parts)); // 转为不可变子列表便于后续处理 } // 可选:打印验证 result.forEach(parts -> System.out.println(parts)); return result; } }
? 进阶建议:若需返回扁平化的 ArrayList(所有子串合并为单层列表),可改用流式操作:public ArrayList splitStringFlat() { return rd.getWord().stream() .flatMap(word -> Arrays.stream(word.split("(?

? 关键注意事项

  • 此正则仅适用于 ASCII 字母字符串;含 Unicode(如中文、emoji)或代理对(surrogate pairs)时需改用 codePointCount + 手动切片;
  • 空字符串或长度
  • 若业务强制要求必须三段(如 "a" → ["a", "", ""]),则需额外补零逻辑,但本题语义明确为“自然分组”,无需填充。

综上,利用 (?