
本文介绍一种基于正则表达式的高效方法,用于从混合结构字符串(如含空格分隔词、括号内逗号分隔项)中统一提取所有语义单元,并存入 list;适用于 apple、apple orange、apple (banana, grape) 等多场景。
在实际开发中,我们常需解析结构松散但有规律的用户输入或配置字符串,例如 "Apple Orange (Banana Ice Cream, Grape)"。这类字符串包含两类语义单元:
- 括号外部分:以空格连接的连续词组(视为一个整体,如 "Apple Orange");
- 括号内部分:以逗号分隔的多项(支持含空格的短语,如 "Banana Ice Cream"),且括号本身不参与语义。
为统一提取所有有效项(忽略括号、逗号、空格等分隔符),推荐使用正则表达式进行一次性分割。核心思路是:将所有可能的“分隔边界”抽象为一个正则模式——即:
- 逗号(前后可带任意空白):\s*,\s*
- 左括号(后接任意空白):\s*\(
- 右括号(前接任意空白):\s*\)
合并后得到完整分隔符正则:
String DELIMITER = "\\s*,\\s*|\\s*\\(|\\s*\\)";
⚠️ 注意:该方案不校验括号配对或嵌套(如 (A, (B,C)) 会错误切分),仅适用于单层括号、格式基本正确的输入。若需严格语法校验,应改用状态机或专用解析器。
立即学习“Java免费学习笔记(深入)”;
以下是完整可运行示例:
import java.util.*;
public class StringSplitter {
private static final String DELIMITER = "\\s*,\\s*|\\s*\\(|\\s*\\)";
public static List extractTerms(String input) {
if (input == null || input.trim().isEmpty()) {
return Collections.emptyList();
}
// 分割后过滤空字符串(避免因首尾空格/多余分隔符产生空项)
return Arrays.stream(input.split(DELIMITER))
.map(String::trim)
.filter(s -> !s.isEmpty())
.toList(); // Java 16+;如用低版本,替换为 .collect(Collectors.toList())
}
public static void main(String[] args) {
String k1 = "Apple";
String k2 = "Apple Orange";
String k3 = "Apple (Banana, Orange, Grape)";
String k4 = "Apple Orange (Banana, Grape)";
String k5 = "Apple Orange (Banana Ice cream, Grape)";
System.out.println(extractTerms(k1)); // [Apple]
System.out.println(extractTerms(k2)); // [Apple Orange]
System.out.println(extractTerms(k3)); // [Apple, Banana, Orange, Grape]
System.out.println(extractTerms(k4)); // [Apple Orange, Banana, Grape]
System.out.println(extractTerms(k5)); // [Apple Orange, Banana Ice cream, Grape]
}
} ✅ 输出完全符合预期:括号外空格连接项保留为整体,括号内逗号分隔项独立成项,且各部分内部空格(如 "Banana Ice cream")被完整保留。
关键注意事项:
- 正则中的 \\s* 确保兼容空格扰动(如 "Apple( Banana ,Grape )" 仍能正确解析);
- .trim() 和 .filter(s -> !s.isEmpty()) 是健壮性必需步骤,防止因输入格式异常引入空字符串;
- 若需兼容 Java 8,将 .toList() 替换为 .collect(Collectors.toList()) 即可;
- 对于含转义字符、嵌套括号或更复杂语法的场景,建议升级为 ANTLR 或手写简易递归下降解析器。
该方案简洁、高效、可读性强,是处理此类“轻量级结构化文本”的首选实践。










