String.split()
方法详解:按正则表达式分割字符串
方法定义
String.split()
方法用于根据给定的正则表达式将字符串分割成多个子字符串,并返回一个字符串数组。
// 1. 基本形式:按正则表达式分割
public String[] split(String regex)
// 2. 限制分割次数的形式
public String[] split(String regex, int limit)
参数说明:
regex
:用于分割字符串的正则表达式limit
:分割的限制:limit > 0
:最多分割成limit
个部分limit = 0
:不限制分割次数,但会移除末尾的空字符串limit < 0
:不限制分割次数,保留所有结果(包括末尾的空字符串)
返回值:
String[]
:分割后的字符串数组
功能说明
split()
方法使用正则表达式作为分隔符,将原字符串分割成多个部分。它从左到右扫描字符串,每当遇到与正则表达式匹配的部分,就在该位置进行分割。
重要特性:
- 分隔符本身不会包含在结果中
- 连续的分隔符会产生空字符串(除非
limit = 0
) - 正则表达式会被编译和匹配,因此需要转义特殊字符
- 空字符串分割返回包含一个空字符串的数组
示例代码
基本用法
public class SplitExample {
public static void main(String[] args) {
// 按逗号分割
String csv = "apple,banana,orange,grape";
String[] fruits = csv.split(",");
System.out.println(Arrays.toString(fruits));
// [apple, banana, orange, grape]
// 按空格分割
String sentence = "Hello world Java programming";
String[] words = sentence.split(" ");
System.out.println(Arrays.toString(words));
// [Hello, world, Java, programming]
// 按多个空白字符分割(包括空格、制表符等)
String text = "apple \t banana orange";
String[] items = text.split("\\s+");
System.out.println(Arrays.toString(items));
// [apple, banana, orange]
}
}
使用 limit
参数
String text = "a,b,c,d,e";
// limit = 2:最多分割成2部分
String[] result1 = text.split(",", 2);
System.out.println(Arrays.toString(result1));
// [a, b,c,d,e]
// limit = 3:最多分割成3部分
String[] result2 = text.split(",", 3);
System.out.println(Arrays.toString(result2));
// [a, b, c,d,e]
// limit = 0:不限制,但移除末尾空字符串
String withTrailing = "a,b,c,";
String[] result3 = withTrailing.split(",", 0);
System.out.println(Arrays.toString(result3));
// [a, b, c] (末尾空字符串被移除)
// limit = -1:不限制,保留所有结果
String[] result4 = withTrailing.split(",", -1);
System.out.println(Arrays.toString(result4));
// [a, b, c, ""] (保留末尾空字符串)
复杂正则表达式分割
// 按多种分隔符分割(逗号、分号、竖线)
String data = "apple,banana;orange|grape,mango";
String[] result = data.split("[,;|]");
System.out.println(Arrays.toString(result));
// [apple, banana, orange, grape, mango]
// 按单词边界分割
String sentence = "Hello123World456Java";
String[] parts = sentence.split("\\d+");
System.out.println(Arrays.toString(parts));
// [Hello, World, Java]
// 按URL中的斜杠分割
String url = "https://example.com/path/to/resource";
String[] pathParts = url.split("/");
System.out.println(Arrays.toString(pathParts));
// [https:, , example.com, path, to, resource]
使用技巧
1. 转义特殊正则字符
// 错误:点号在正则中表示任意字符
// String[] parts = "file.txt".split("."); // 返回空数组
// 正确:转义点号
String[] parts = "file.txt".split("\\.");
System.out.println(Arrays.toString(parts)); // [file, txt]
// 其他需要转义的字符:[, ], (, ), {, }, ., *, +, ?, ^, $, \, |, /
String[] escaped = "a|b.c*d".split("[|.]"); // 按 | 或 . 分割
2. 处理空白字符
// 按任意空白字符分割
String text = "apple \t banana\norange grape";
String[] items = text.split("\\s+");
System.out.println(Arrays.toString(items));
// [apple, banana, orange, grape]
// 按换行符分割(跨平台)
String multiLine = "line1\nline2\r\nline3";
String[] lines = multiLine.split("\\r?\\n|\\r");
System.out.println(Arrays.toString(lines));
// [line1, line2, line3]
3. 移除空字符串
// 移除分割结果中的空字符串
String messy = "apple,,banana,,orange,";
String[] raw = messy.split(",");
String[] clean = Arrays.stream(raw)
.filter(s -> !s.isEmpty())
.toArray(String[]::new);
System.out.println(Arrays.toString(clean)); // [apple, banana, orange]
4. 限制分割次数的实际应用
// 解析键值对(只分割第一个等号)
String config = "name=John Doe=Developer";
String[] pair = config.split("=", 2);
if (pair.length == 2) {
String key = pair[0]; // "name"
String value = pair[1]; // "John Doe=Developer"
System.out.println(key + " -> " + value);
}
常见错误
1. 忘记转义正则特殊字符
// 错误示例
String[] result = "1.2.3.4".split(".");
// 返回空数组,因为 "." 匹配所有字符
// 正确做法
String[] result = "1.2.3.4".split("\\.");
2. 忽略末尾空字符串的处理
String trailing = "a,b,c,";
String[] result1 = trailing.split(","); // limit=0 的效果
String[] result2 = trailing.split(",", -1); // 保留末尾空字符串
System.out.println(result1.length); // 3
System.out.println(result2.length); // 4
3. 分割空字符串
String empty = "";
String[] result = empty.split(",");
// 返回 [""],长度为1,不是0
System.out.println(result.length); // 1
4. 分隔符不存在的情况
String text = "hello";
String[] result = text.split(",");
// 返回 ["hello"],原字符串作为唯一元素
System.out.println(Arrays.toString(result)); // [hello]
注意事项
- 正则表达式安全:确保正则表达式语法正确,否则会抛出
PatternSyntaxException
- 性能考虑:对于简单的字符分割,考虑使用
StringTokenizer
或手动解析 - 内存使用:大字符串分割会产生大量小字符串对象
- 空结果处理:始终考虑空字符串和空结果数组的情况
- 编码问题:确保字符串编码与正则表达式预期一致
最佳实践
1. 预编译正则表达式(大量重复操作时)
// 对于频繁使用的正则表达式
private static final Pattern CSV_PATTERN = Pattern.compile(",");
public static String[] splitCsv(String csv) {
return CSV_PATTERN.split(csv);
}
2. 创建工具方法
public class StringUtils {
// 安全的分割方法
public static String[] safeSplit(String str, String regex) {
if (str == null || regex == null) {
return new String[0];
}
return str.split(regex);
}
// 移除空字符串的分割
public static String[] splitAndRemoveEmpty(String str, String regex) {
if (str == null || regex == null) {
return new String[0];
}
return Arrays.stream(str.split(regex))
.filter(s -> s != null && !s.isEmpty())
.toArray(String[]::new);
}
}
3. 处理CSV文件
// 简单的CSV解析(不支持引号包裹的逗号)
public static List<String> parseCsvLine(String line) {
return Arrays.stream(line.split(","))
.map(String::trim) // 移除前后空白
.collect(Collectors.toList());
}
4. 验证分割结果
public static boolean isValidSplit(String input, String regex, int expectedParts) {
String[] parts = input.split(regex);
return parts.length == expectedParts;
}
性能优化
1. 避免在循环中重复分割
// 不推荐
for (String line : lines) {
String[] parts = line.split(","); // 每次都编译正则
// 处理parts
}
// 推荐:预编译模式
Pattern pattern = Pattern.compile(",");
for (String line : lines) {
String[] parts = pattern.split(line);
// 处理parts
}
2. 对于简单分隔符,考虑替代方案
// 对于单个字符分隔符,手动解析可能更快
public static List<String> manualSplit(String str, char delimiter) {
List<String> result = new ArrayList<>();
int start = 0;
for (int i = 0; i < str.length(); i++) {
if (str.charAt(i) == delimiter) {
result.add(str.substring(start, i));
start = i + 1;
}
}
result.add(str.substring(start)); // 添加最后一部分
return result;
}
3. 使用 StringBuilder 处理大文本
// 对于需要频繁修改的文本
StringBuilder sb = new StringBuilder(largeText);
// 如果需要分割,转换为字符串
String[] parts = sb.toString().split(regex);
总结
String.split()
是 Java 中强大的字符串分割工具,关键要点:
- 核心功能:使用正则表达式分割字符串
- 正则表达式:需要正确转义特殊字符
- limit 参数:控制分割行为和结果
- 常见场景:CSV解析、路径处理、文本分析等
- 最佳实践:
- 正确转义正则特殊字符
- 理解
limit
参数的不同效果 - 处理空字符串和边界情况
- 对于频繁操作,考虑预编译正则表达式
掌握 split()
方法能有效处理各种字符串分割需求,特别是在数据解析和文本处理场景中非常有用。通过遵循最佳实践,可以写出更健壮、高效的代码。