String 方法的split 其实是很有学问的,他有很多的特殊情况。我们来梳理一下:

备注:limit 是 split(String regex, int limit ) 方法的第二个参数,“ab”.split(“a”) 其实调用的是"ab".split(“a”,0)方法。

         1.如果字符串最前面有匹配的字符串  则返回的字符串数组 第一个为空
         System.out.println(Arrays.toString("-1".split("-")));
         [, 1]
         2.如果limit 为 0 ,后续分割的字符串长度小于0,那么后续的字符串就不会继续返回)
         System.out.println(Arrays.toString("  hello world!  ".split(" ")));
         [, , hello, world!]
         System.out.println(Arrays.toString("3-2-abc---".split("-")));
         [3, 2, abc]
         System.out.println(Arrays.toString("aaaa".split("a")));
         这个因为是所有的元素都是空,而且limit 是 0  所以返回的就是空的 具体可以看下源码
         System.out.println(Arrays.toString("-1---".split("-")));
         [, 1]
         3.如果没有匹配到字符串,则返回整个字符串  不关心limit 参数
         System.out.println(Arrays.toString("-1---1-1-".split("c",2)));
         [-1---1-1-]
         4.如果设置了limit,那么返回的最长长度就是limit  最后一个为没有分割的后续字符串
         System.out.println(Arrays.toString("-1---1-1-".split("-",1)));
         [-1---1-1-]
         System.out.println(Arrays.toString("-1---1-1-".split("-",2)));
         [, 1---1-1-]
         5.如果limit 不为 0 ,后续分割的字符串长度小于0,后续的字符串也会继续返回
         System.out.println(Arrays.toString("-1--".split("-",4)));
         [, 1, , ]
         6.如果limit 不为 0 ,且设置的长度大于分割后整个数组的长度,后续的字符串也会继续返回
         System.out.println(Arrays.toString("-1--".split("-",5)));
         [, 1, , ]
         7.如果分割得到的所有字符串都是空串 那么返回的结果数组是空的
         System.out.println(Arrays.toString("aaaa".split("a")));
         8.如果limit 为1 那么直接返回整个字符串,不管是不是找到了子串,具体原因看源码
         System.out.println(Arrays.toString("-1---1-1-".split("1",1)));
         [-1---1-1-]
         System.out.println(Arrays.toString("-1---1-1-".split("a",1)));
         [-1---1-1-]

我们看下源码:

split()方法,会直接调用下面的 split(String regex, int limit) 方法
    public String[] split(String regex) {
        return split(regex, 0);
    public String[] split(String regex, int limit) {
        /* fastpath if the regex is a
         (1)one-char String and this character is not one of the
            RegEx's meta characters ".$|()[{^?*+\\", or
         (2)two-char String and the first char is the backslash and
            the second is not the ascii digit or ascii letter.
        char ch = 0;
        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))
            int off = 0;
            int next = 0;
            boolean limited = limit > 0;
            ArrayList<String> list = new ArrayList<>();
            //如果找到了要找的字符
            while ((next = indexOf(ch, off)) != -1) {
            //如果说没有设置limit   或者是在limit 范围内 直接添加进去
                if (!limited || list.size() < limit - 1) {
                    list.add(substring(off, next));
                    off = next + 1;
                } else {    // last one  最后一个
                    //assert (list.size() == limit - 1);
                    list.add(substring(off, value.length));
                    off = value.length;
                    break;
            // If no match was found, return this  如果没有找到字符 则直接返回原来的字符串
            if (off == 0)
                return new String[]{this};
            // Add remaining segment  
            if (!limited || list.size() < limit)
                list.add(substring(off, value.length));
            // Construct result
            int resultSize = list.size();
            if (limit == 0) {
            //从数组的最后往前找 如果是空字符串 那么 数组长度减减
                while (resultSize > 0 && list.get(resultSize - 1).length() == 0) {
                    resultSize--;
            String[] result = new String[resultSize];
            return list.subList(0, resultSize).toArray(result);
        return Pattern.compile(regex).split(this, limit);

其实记住特殊情况还是比较复杂的,关键是记住split 的算法。
首先从index =0 开始,找到分割符所在的位置,进行截取,放到list 里面。然后从上次截取的位置 + 1 开始,找下一个字符出现的问题,继续截取。最后把最后一个位置到末尾的字符串截取放到List 里面。最后从末尾往前进行空字符串处理。

String str="1234@abc"; String[] a = str.split("@"); System.out.println("处理结果: "+a[0]+","+a[1]); //输出的是: 处理结果: 1234,abc 对于分割的字符(串),通常是常 我在应用中用到一些,给大家总结一下,仅供大家参考: 1、如果用“.”作为分隔的话,必须是如下写法:String.split("\\."),这样才能正确的分隔开,不能用String.split("."); 2、如果用“|”作为分隔的话,必须是如下写法:String.split("\\|"),这样才能正确的分隔开,
大家都知道split方法是将一个字符串作为this的分隔符来传入方法中,而返回值是一个字符串数组。 而总有一些不安分的一些人,拿一些不常用符号当这个分隔符为“ . $ | ( ) [ { ^ ? * + \” 这些符合时,这个方法就会出现一个小问题。在split方法中的正则表达式中有可能会搜索不到这些特殊符号,导致拆分失败。 第一种情况:所有字符分开,每个字符为一个元素...
private static final String REGEX = ";"; public static void main(String[] args) throws Exception { split(""); split(";"); split(";", -1); split("1;;"); split("1;;",-1); 解决 fastjson 泛型报错 : java.lang.ClassCastException: com.alibaba.fastjson.JSONObject cannot be cast to X 24836
Android研发曹新雨: <network-security-config xmlns:android="http://schemas.android.com/apk/res/android"> <domain-config cleartextTrafficPermitted="true"> <domain includeSubdomains="true">mi.com</domain> <trust-anchors> <certificates src="user" /> </trust-anchors> </domain-config> <base-config cleartextTrafficPermitted="true"> <trust-anchors> <certificates src="user" /> </trust-anchors> </base-config> </network-security-config> Windows charles Https抓包详解 Android研发曹新雨: 有一次用小米手机系统浏览器下载Charles证书,死活下载不下来,后来用了QQ浏览器下载,很轻松就下载了。真的是,害惨了。不能清晰相信系统工具就完全没问题。 Java TreeMap 和 TreeSet 源码解析 CSDN-Ada助手: Java里使用equals()和==的区别是什么? FileObserver源码分析 CSDN-Ada助手: 推荐 Java 技能树:https://edu.csdn.net/skill/java?utm_source=AI_act_java