String的split这些细节你需要了解

1. 背景

String的split方法在项目中使用很广泛,但是这里面其实有些坑,截取的字段数目可能不是想要的,本文阐述这些内容,增加记性。

2. split方法介绍

首先可以看下javadoc中关于split的介绍。

String []  split(String regex)
Splits this string around matches of the given [regular expression](https://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html#sum).

String[] split(String regex, int limit)
Splits this string around matches of the given [regular expression](https://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html#sum).

简而言之,split方法就是根据输入的正则表达式分割字符串。
那么这又有什么毛病咧,别急。

3. split的limit参数

在项目中,经常被使用的就是第一个方法,输入一个参数regex(其实limit为0),仔细看下官方的描述

This method works as if by invoking the two-argument [`split`](https://docs.oracle.com/javase/7/docs/api/java/lang/String.html#split(java.lang.String,%20int)) method with the given expression and a limit argument of zero. Trailing empty strings are therefore not included in the resulting array.

该方法会导致后面的空串被去掉,比如
“beijing:and:shenzhen:”, 用:分割后,得到的结果为{ "beijing", "and", "shenzhen" },而有时项目是希望得到4个字段的,会造成线上严重问题。

4. split的regex参数

该参数是个正则表达式,那么要记住,在传入正则表达式的特殊字符时,可能会出呼意料的结果,要加上转义字符。比如
“beijing|and|shenzhen”, 用"//|"分割后,得到的结果为{ "beijing", "and", "shenzhen" },而有时项目是希望得到4个字段的,会造成线上严重问题。
具体有哪些特殊字符,看下split的源码介绍。

 if (((regex.value.length == 1 &&
             ".$|()[{^?*+\\".indexOf(ch = regex.charAt(0)) == -1) ||
             (regex.length() == 2 &&
              regex.charAt(0) == '\\' &&
              (((ch = regex.charAt(1))-'0')|('9'-ch)) < 0 &&
              ((ch-'a')|('z'-ch)) < 0 &&
              ((ch-'A')|('Z'-ch)) < 0)) &&
            (ch < Character.MIN_HIGH_SURROGATE ||
             ch > Character.MAX_LOW_SURROGATE))
        {
     ...
}

if条件判断里面是重点,主要分为两个部分:

  1. 单字符的字符串并且该字符不是为正则中的特殊字符,比如.$|()[{^?*+\
(regex.value.length == 1 &&
             ".$|()[{^?*+\\".indexOf(ch = regex.charAt(0)) == -1)
  1. 两个字符的字符串,第一个字符为转义字符(\),第二个字符非数字或这字母,其实就是将特殊字符作为分割符号。
 (((ch = regex.charAt(1))-'0')|('9'-ch)) < 0 &&
              ((ch-'a')|('z'-ch)) < 0 &&
              ((ch-'A')|('Z'-ch)) < 0)) &&
            (ch < Character.MIN_HIGH_SURROGATE ||
             ch > Character.MAX_LOW_SURROGATE)

在这里需要指出的是,此处判断为非数字或字母采用了或(|)的位运算,很巧妙。

你可能感兴趣的:(String的split这些细节你需要了解)