Java String.split(".") 返回空数组,读取第一个元素时报越界
String.split 的句点参数是正则通配符,配合默认移除尾部空字段会得到空数组。转义字面句点,再按字段契约决定是否保留末尾空值。
想按英文句点拆开字符串,结果数组长度却为零,接着访问下标 0 又抛出 ArrayIndexOutOfBoundsException:
String text = "alpha.beta.gamma";
String[] parts = text.split(".");
System.out.println(parts[0]);
应先检查分隔规则。String.split 的参数是正则表达式,英文句点在正则里并不表示普通句点。本文针对标准 Java 字符串 API;split 从 Java 1.4 提供,后文的 Pattern.quote 从 Java 5 提供。
任意字符匹配与尾部空字段一起造成空数组
在默认正则模式下,. 匹配除行终止符之外的任意字符。示例字符串没有换行,因此每个字符都被当作分隔符,切出来的片段全是空字符串。
单参数 split(regex) 又等同于 split(regex, 0),会丢弃尾部空字符串。这里所有片段都为空,最终长度就是零。若输入包含换行,结果可能不同,不能把“句点总会得到空数组”当成通用规则。
检查时先看数组长度与使用的正则,再看输入是否含行终止符。给数组访问加长度判断可以防止第二个异常,但并不会让错误的分隔规则变正确。
把句点作为字面量传入
固定使用英文句点分隔时,需要同时处理 Java 字符串和正则表达式两层转义:
import java.util.Arrays;
public class SplitExample {
public static void main(String[] args) {
String text = "alpha.beta.gamma";
String[] parts = text.split("\\.");
System.out.println(Arrays.toString(parts));
// 预期 [alpha, beta, gamma]
}
}
Java 源码中的 "\\." 传到正则引擎后是 \.,表示字面句点。不要写成 "\.",单个反斜杠加句点不是合法的 Java 字符串转义。
如果分隔符来自配置,并且配置表示普通文本,可以使用 Pattern.quote:
String delimiter = ".";
String[] parts = text.split(
java.util.regex.Pattern.quote(delimiter)
);
这个片段沿用前面的 text。如果配置本来允许填写正则,就不能统一加 quote,否则会改变配置含义。
需要保留末尾空字段时,再设置 limit
修正句点后,末尾空字段是否保留仍由接口约定决定:
String text = "alpha.beta.";
String[] dropped = text.split("\\.");
String[] kept = text.split("\\.", -1);
// dropped 预期为两个元素:alpha、beta
// kept 预期为三个元素:alpha、beta、空字符串
负数 limit 保留尾部空字符串;正数则限制结果数量,最后一个元素保留剩余内容。只给错误的 split(".") 加上 -1,仍会按任意字符拆分,不能替代转义句点。
验证时覆盖普通文本、连续句点、末尾句点、空字符串及不含句点的输入。没有匹配到分隔符时,结果包含原字符串;空输入也不能简单假定会返回长度为零的数组。
若下游按字段位置读取数据,应一起核对字段数量和空字段策略。上线前保留原始输入与旧规则,发现解析变化时回退局部规则并重新解析受影响记录,不要用忽略越界异常的方式吞掉数据。


