在Java开发中,字符串分割是高频操作,很多场景下我们需要用正则表达式作为分割依据,同时精确控制分割后产生的空白符是否保留、如何移除。如果处理不当,很容易出现分割结果不符合预期的问题,比如多余的空字符串、需要保留的空白被误删等。

Java字符串分割的基础方法
Java中字符串分割最常用的方法是String.split(String regex),该方法接收正则表达式作为参数,按照正则匹配的内容分割字符串,返回分割后的字符串数组。默认情况下,如果分割后末尾出现空字符串,会被自动丢弃。
我们来看一个基础的分割示例,用逗号分割字符串:
public class SplitDemo {
public static void main(String[] args) {
String str = "apple,banana,orange,,grape,";
String[] result = str.split(",");
for (String s : result) {
System.out.println("[" + s + "]");
}
}
}
上述代码的输出结果是:
[apple] [banana] [orange] [] [grape]
可以看到,连续逗号之间会产生空字符串,而末尾的空字符串被自动丢弃了。
空白符处理的常见需求与问题
实际开发中,我们经常遇到需要同时处理分割符和空白符的场景,比如字符串中分割符前后可能有空格,我们希望分割后自动去掉这些空格,或者保留特定的空白。常见的问题包括:
- 分割后每个元素前后有多余空格,需要统一移除
- 分割符可能是多个空白符的组合,需要准确识别分割点
- 需要保留元素内部的空白,只移除分割符带来的空白
- 连续分割符产生的空字符串需要过滤,或者保留空字符串
精确控制空白符移除的实现方案
方案一:正则中直接包含空白符匹配
如果空白符是固定出现在分割符前后,可以把空白符匹配直接写入正则表达式。比如分割符是逗号,逗号前后可能有0个或多个空格,正则可以写成\s*,\s*,其中\s*表示匹配0个或多个空白符(包括空格、制表符、换行符等)。
public class SplitDemo2 {
public static void main(String[] args) {
String str = " apple , banana , orange ,, grape ";
// 正则匹配逗号前后0个或多个空白符作为分割点
String[] result = str.split("\s*,\s*");
for (String s : result) {
System.out.println("[" + s + "]");
}
}
}
输出结果为:
[apple] [banana] [orange] [] [grape]
这种方式会自动去掉每个元素前后的空格,但是连续逗号之间还是会产生空字符串,末尾的空字符串依然会被丢弃。
方案二:分割后单独处理空白符
如果需要更灵活的控制,比如过滤掉空字符串,或者对空白符的移除规则更复杂,可以先分割,再遍历数组处理每个元素。我们可以结合String.trim()方法去掉元素前后的空白,再过滤掉处理后的空字符串。
import java.util.ArrayList;
import java.util.List;
public class SplitDemo3 {
public static void main(String[] args) {
String str = " apple , banana , orange ,, grape ";
String[] splitArr = str.split(",");
List<String> resultList = new ArrayList<>();
for (String s : splitArr) {
// 去掉前后空白
String trimmed = s.trim();
// 过滤掉空字符串
if (!trimmed.isEmpty()) {
resultList.add(trimmed);
}
}
for (String s : resultList) {
System.out.println("[" + s + "]");
}
}
}
输出结果为:
[apple] [banana] [orange] [grape]
这种方式可以灵活控制处理逻辑,比如如果需要保留元素内部的空白,只移除前后的,用trim()就非常合适;如果需要移除所有空白,可以改用replaceAll("\s+", "")处理每个元素。
方案三:使用正则匹配分割并保留特定内容
如果需要更复杂的分割规则,比如分割符是多个空白符,或者分割后需要保留分割符相关的信息,可以使用Pattern和Matcher类配合正则的捕获组来实现。比如我们想按照一个或多个空白符分割字符串,同时保留非空白的内容:
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class SplitDemo4 {
public static void main(String[] args) {
String str = "hello world java regex";
// 正则匹配一个或多个非空白字符,作为需要保留的内容
Pattern pattern = Pattern.compile("\S+");
Matcher matcher = pattern.matcher(str);
List<String> resultList = new ArrayList<>();
while (matcher.find()) {
resultList.add(matcher.group());
}
for (String s : resultList) {
System.out.println("[" + s + "]");
}
}
}
输出结果为:
[hello] [world] [java] [regex]
这种方式不需要显式处理空白符,因为正则直接匹配非空白的内容,天然过滤了空白分割符和多余的空白。
注意事项与常见误区
- 正则中的反斜杠需要转义,比如匹配
s需要写成\s,因为Java字符串本身会转义反斜杠。 split方法的第二个参数limit可以控制分割的次数和空字符串的保留,比如split(",", -1)会保留所有分割后的空字符串,包括末尾的。- 如果需要匹配特殊的正则字符,比如点号
.、竖线|,需要加反斜杠转义,比如分割点号需要写成\.。 - 不要混淆
trim()和空白符正则的作用,trim()只移除前后的空白,而\s可以匹配所有位置的空白符。
实际开发中需要根据具体的业务需求选择合适的方案,简单的场景用split配合正则即可,复杂的场景可以结合遍历处理或者Pattern、Matcher类实现更精准的控制。