java使用split遇到的坑

使用split的时候,要多注意下标。

split方法

    public String[] split(String regex) {
        return split(regex, 0);
    }

继续往里看:

public String[] split(String regex, int limit) {
    //....
    return Pattern.compile(regex).split(this, limit);
}

split()方法内部,其实是用Pattern去处理的。
Pattern是一个正则表达式经编译后的表现模式。
Pattern compile(String regex) 表示将给定的正则表达式编译并赋予给Pattern类。
Patter还有matcher()、find()、group()等方法。

而split(String regex, int limit),通过设置limit指定拆分成几部分。
如果只拆成两部分,如下:

String [] parts = str.split(",", 2);

使用split

  • split()的参数regex,是正则表达式。

比如,通过.去分隔:

String[] part=str.split("\\.");

通过,去分隔:

String[] part=str.split(",");

通过任意空格去分隔:

String[] part=str.split("\\s+");

数组下标越界

比如,以下方法,可能会出错:

public void splitError(String str) {
    if (str == null) {
        return;
    }
    String[] part = str.split(",");
    String s0 = part[0];
    String s1 = part[1];
}

假如str的分隔符后面没有数据,比如"a,",split拆分后的 String[]为{a}。
又或者str没有分隔符,比如"abc",split拆分后的 String[]为{abc}
明显part[1]会报错:java.lang.ArrayIndexOutOfBoundsException: 1。
因此,修改代码:

public void splitError(String str) {
    if (str == null) {
        return;
    }
    String[] part = str.split(",");
    String s0 = part[0];
    //添加以下判断
    if (part.length > 1) {
        String s1 = part[1];
    }
}

下标为0,也可能会越界

看似没什么问题了,但是实际上还是可能出错。
假如str为"," ,那么split拆分后的 String[]为{},数组为空,因此part[0]会报错:java.lang.ArrayIndexOutOfBoundsException: 0。
修改代码:

public void splitError(String str) {
    if (StringUtils.isEmpty(str)) {
        return;
    }
    String[] part = str.split(",");

    if (part.length == 1) {
        String s0 = part[0];
    } else if (part.length > 1) {
        String s0 = part[0];
        String s1 = part[1];
    }
}

拆分前,先检查是否包含分隔字符

除了拆分之后,使用length判断下标。也可以在拆分之前,先检查是否包含分隔字符。

public void splitError(String str) {
    if (StringUtils.isEmpty(str)) {
        return;
    }
    if(str.contais(",")){
        String[] part = str.split(",");
        String s=part[0];
    }

}

检查最后一个分隔符后是否有内容

《阿里巴巴java开发手册》上面有这样一条:

【推荐】使用索引访问用 String 的 split 方法得到的数组时,需做最后一个分隔符后有无
内容的检查,否则会有抛 IndexOutOfBoundsException 的风险。
说明:
String str = "a,b,c,,"; 
String[] ary = str.split(","); 
// 预期大于 3,结果是 3
System.out.println(ary.length);

结论

记住,在使用split拆分字符串时,想获取字符串数组对应下标的数据,必须先判断数组长度。

posted on 2020-04-19 21:19  乐之者v  阅读(3244)  评论(0编辑  收藏  举报

导航