精华内容
下载资源
问答
  • HashMap中红黑树TreeNode的split方法源码解读,对split方法源码的上下文/变量定义,及所调用的关键方法都给出了详细解释说明,欢迎指正
  • 主要介绍了String split方法实现过程图解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
  • 主要详细介绍了Java的split方法使用说明,十分的细致全面,有需要的小伙伴可以参考下。
  • 本文实例讲述了python中split方法用法。分享给大家供大家参考。具体分析如下: split 是非常重要的字符串方法,它是join的逆方法,用来将字符串分割成序列 >>> '1+2+3+4+5'.split('+') ['1', '2', '3', '4', '5'] >...
  • Java split方法详细讲解

    千次阅读 2020-12-25 18:37:03
    方法1:split(String regex) split()方法:分割字符串,参数regex称为分割符,可以使用正则表达式来表示 public String[] split(String regex) { return split(regex, 0); } 入门案例1 分割符可以是任意字母,...

    今天是圣诞节,我是中国人,无视圣诞节。
    文章可能有点长,看下来必定有所收获。
    没有学过正则表达式的去b站看,一个半小时应该可以看完,要看请点这里
    这是必备的前置技能,不懂得话没法真正明白split用法

    方法1:split(String regex)

    split()方法:分割字符串,参数regex称为分割符,可以使用正则表达式来表示

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

    入门案例1

    分割符可以是任意字母,符号,数字,字符串等等,这个基本都会

        @Test
        public void splitDemo1(){
            String str= "1a2";
            String[] split = str.split("a");
            //split:{"1","2"}
            for (int i = 0; i < split.length; i++) {
                System.out.println(split[i]);
            }
        }
    

    运行结果

    1
    2
    

    注意:String类型是不可变的!分隔符会把字符串拆成若干个子字符串,然后生成一个String数组

    入门案例2

    分割符可以用正则表达式来表示

    @Test
    public void splitDemo2(){
        String str= "a33b444c555d";
        //正则表达式中\d+表示一个或多个数字,java中\\表示一个普通\
        //String[] split = str.split(Pattern.compile("\\d+").toString());
        //两种写法都是一样的,下面写法简洁
        String[] split = str.split("\\d+");
        for (int i = 0; i < split.length; i++) {
            System.out.println(split[i]);
        }
    }
    

    运行结果

    a
    b
    c
    d
    

    入门案例3

    正则表达式篇中讲过,正则表达式中有一些特殊的字符,这些字符本身有特殊含义,加了\后表示仅匹配字符本身
    在这里插入图片描述
    java中两个反斜杠才表示一个\

    @Test
    public void splitDemo3(){
        String str= "aaa|bbb|ccc";
        //使用|作为分隔符,其余特殊字符同理
        String[] split = str.split("\\|");
        for (int i = 0; i < split.length; i++) {
            System.out.println(split[i]);
        }
    }
    

    运行结果

    aaa
    bbb
    ccc
    

    入门案例4

    分隔符可以有多个,用|隔开,|分支结构:左右两边表达式之间"或"关系,匹配左边或者右边
    这是属于上篇的内容,这里复习一下。正则的语法规则可以在这里灵活运用

    @Test
    public void splitDemo4(){
        String str= "aaa,bbb#ccc";
        //使用,和#分割字符串
        String[] split = str.split(",|#");
        for (int i = 0; i < split.length; i++) {
            System.out.println(split[i]);
        }
    }
    

    运行结果

    aaa
    bbb
    ccc
    

    分隔符三个特殊位置

    入门案例的分隔符都是在字符串中间,非常好切割,但是如果出现以下任意其一,该怎么分割?

    1.字符串开头有分隔符
    2.分隔符相互紧挨着
    3.字符串最尾部有分割符

    总结:
    字符串开头出现的分隔符将分隔出一个空字符串以及其余部分的正常分隔
    字符串最尾部出现的分隔符,末尾会分割出一个空字符串
    分隔符紧挨着,分隔符之间也会分割出一个空字符串

    特殊案例1

    分隔符紧挨着,分隔符之间也会分割出一个空字符串

    @Test
    public void demo(){
        String str= "19997";
        String[] split = str.split("9");
        for (int i = 0; i < split.length; i++) {
            System.out.println(split[i]);
        }
    }
    

    两个9之间会分割出一个空字符串,所以会出现两个空字符串,前面的1和7正常分割
    在这里插入图片描述

    特殊案例2

    字符串开头出现的分隔符将分隔出一个空字符串以及其余部分的正常分隔
    字符串最尾部出现的分隔符,其余部分正常分隔,末尾会分割出一个空字符串

        @Test
        public void demo(){
            String str= "yky";
            String[] split = str.split("y");
            System.out.println(split.length);
            System.out.println(Arrays.toString(split));
        }
    

    运行结果:

    2
    [, k]
    //按照我们的结论,返回的数组应该是["",k,""]才对
    

    其实不是结论错了,而是参数limit的问题,接下来
    点进去split方法查看,发现调用的是另一个重载方法split(String regex, int limit)
    分割时末尾的字符串被丢弃了

    public String[] split(String regex) {
        return split(regex, 0);		
        //3.如果 n = 0,匹配到多少次就切割多少次,数组可以是任何长度,并且结尾空字符串将被丢弃。
    }
    

    方法2:split(String regex,int limit)

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

    可以看出只填一个正则表达式的话,limit默认是0,regex表示正则表达式,limit参数控制分割的次数

    limit用法:

    1.如果 limit > 0,(从左到右)最多分割 n - 1 次,数组的长度将不会大于 n,结尾的空字符串不会丢弃

    2.如果 limit < 0,匹配到多少次就分割多少次,而且数组可以是任何长度。结尾的空字符串不会丢弃

    3.如果 limit = 0,匹配到多少次就分割多少次,数组可以是任何长度,并且结尾空字符串将被丢弃

    也就是说,使用split方法时,如果只填一个正则表达式,结尾空字符串将被丢弃

    看看源码大概怎么说的

           ArrayList<String> matchList = new ArrayList<>();
           //......
            int resultSize = matchList.size();
            if (limit == 0)
                while (resultSize > 0 && matchList.get(resultSize-1).equals(""))
                    resultSize--;
    			String[] result = new String[resultSize];
    		//...
    

    先从ArrayList的长度开始遍历,如果发现是空字符串,则长度-1,该长度也等于字符串数组的长度

    进阶案例:

    limit>0限制分割次数

    1.如果 limit > 0,(从左到右)最多分割 limit - 1 次,数组的长度将不会大于limit,结尾的空字符串不会丢弃

    limit=1,分割0次,即不分割,将原字符串装进数组并返回

    limit如果太大超出了匹配次数,匹配到多少次就分割多少次

    String[] split = "abc".split("b",999);	//limit=999,但是b只匹配到一次,所以只能分割一次
    //split:{"a","c"}
    
    String[] split2 = "abc".split("b",1);	//不切割
    //split2:{"abc"}
    

    结尾的空字符串不会丢弃

        @Test
        public void demo1(){
            //limit=3,切割2次,末尾会分割出一个""空字符串
            String[] split = "abcb".split("b",3);
                System.out.println(split.length);	//数组长度是3
            //split:{"a","c",""}
        }
    

    limit<0不限制分割次数

    2.如果 limit < 0,匹配到多少次就分割多少次,而且数组可以是任何长度。结尾的空字符串不会丢弃
    在这里插入图片描述

    limit=0不限制分割次数

    这个是最常用的,要注意结尾的空字符串将会丢弃

    使用o取切割"boo:and:foo",分割后得到数组的长度是3,两个空字符串被丢弃
    在这里插入图片描述

    特殊案例3(字符串不包含分隔符)

    当字符串不包含分隔符时,返回数组只包含一个元素(该字符串本身)

    @Test
    public void demo2(){
        String str= "abcde";
        String[] split = str.split("f",-1);
        //split:{"abcde"}
        System.out.println(split.length);	//1
    }
    

    特殊案例4(字符串只含有分隔符本身)

    字符串只含有分隔符本身,这种切割没啥意义,但还是测试下吧

    切割出三个空字符串,开头结尾,相连的地方各一个空字符串
    在这里插入图片描述

    limit=0时,空字符会被丢弃,返回空数组,长度为0
    在这里插入图片描述

    无聊案例1(切割空字符串)

    经过测试,分隔符是空字符串""还是任意正则表达式,都会返回带空字符串的数组(空字符串也是字符串)
    在这里插入图片描述

    无聊案例2(分隔符是空字符串)

    这种切法非常奇怪,字符串的最末尾会分割出一个"",要去掉的话limit=0即可

    @Test
    public void demo2(){
        String str= "abc";
        String[] split = str.split("",-1);
        System.out.println(split.length);
    }
    

    练习

    截取自jdk源码,Regex分隔符,limit取值,Result截取后的数组

    字符串 “boo:and:foo”
    在这里插入图片描述
    能看懂说明split已经理解了

    知识补充:

    零宽断言(预搜索)

    split里还可以使用零宽断言(预搜索)

    @Test
    public void splitDemo(){
        //分割符是#,但是只要#后面跟123的那个#,其余#不要
        String str= "22222#123#2234";
        String[] split = str.split("#(?=123)");
        for (int i = 0; i < split.length; i++) {
            System.out.println(split[i]);
        }
    }
    

    运行结果:

    22222
    123#2234
    

    字符边界^$

    split里还可以使用字符边界^$

    ^匹配行首,$匹配行尾,字符边界匹配时是零宽的,匹配的是位置

    @Test
    public void demo1(){
        //\r\n在window时回车+换行的意思
        String str = "#第一章\r\n#第二章";
        Pattern pattern =Pattern.compile("^#",Pattern.MULTILINE);
        String[] split = str.split(pattern.toString(),-1);
        //String[] split = str.split("^#",-1);
        for (int i = 0; i < split.length; i++) {
            System.out.println(split[i]);
        }
    }
    

    返回的字符串数组是{"",“第一章\r\n#第二章”}
    分隔符在行首会分割出一个空串"",其余部分正常分割。但是第二个#没有分割,这个出乎意料。

    Pattern pattern =Pattern.compile("^#",Pattern.MULTILINE);
    这个上篇正则表达式讲过,pattern 是正则表达式的编译形式,同时开启多行模式
    pattern.toString() 是正则表达式的字符串形式

    我猜想:问题一定出在pattern.toString(),既然是字符串形式

    Pattern pattern =Pattern.compile("^#",Pattern.MULTILINE);
    String[] split = str.split(pattern.toString(),-1);

    这两行代码我直接写成一行就行了String[] split = str.split("^#",-1);

    开启多行模式似乎不是用在这里的。我只想切割每行行首的#,其余的#不想切割,那怎么开启多行模式?

    我仔细想了一下,我上面用的都是String类的split方法,跟Pattern类的多行模式扯不上边啊。
    这么一想,有道理,去Pattern类看看有没有类似的方法
    在这里插入图片描述
    不光有,还有两。用法肯定是类似的,但是CharSequence是啥?没见过

    public final class String
        implements java.io.Serializable, Comparable<String>, CharSequence {
    

    idea通过快捷键crtl + alt + B看接口的实现关系在这里插入图片描述
    我发现String类实现了这个CharSequence接口,那参数的意思是输入一个String字符串,而匹配规则已经写在Pattern类里了。

        @Test
        public void demo1(){
            Pattern pattern =Pattern.compile("^#",Pattern.MULTILINE);
            //\r\n在window时回车+换行的意思
            String str = "#第一章\r\n#第二章\r\n#第三章";
            String[] split = pattern.split(str, -1);
            System.out.println("数组的长度是:"+split.length);
            //split:{"","第一章","第二章","第三章"}
            for (int i = 0; i < split.length; i++) {
                System.out.print(split[i]);
            }
        }
    

    运行结果:

    数组的长度是:4
    第一章
    第二章
    第三章
    

    开启多行模式的确有效,数组第一个位置是空字符串,打印时不会打出来,那么是怎么判断行首行尾的位置?
    是按照空格,制表符,换行,回车判断的?所以我做了个实验
    字符串分别加了以\r,\n,\r\n,空格,\t
    再根据数组的长度,就知道分隔了多少次,从而知道判断行首的标准是什么。
    如果是4,意味着该字符用来判断行首行尾
    如果是2,说明只分隔了一次,字符串最前面分隔了一次

    @Test
    public void demo2(){
        Pattern pattern =Pattern.compile("^#",Pattern.MULTILINE);
        String str = "#第一章\r#第二章\r#第三章";
        String str2 = "#第一章\n#第二章\n#第三章";
        String str3 = "#第一章\r\n#第二章\r\n#第三章";
        String str4 = "#第一章 #第二章 #第三章";
        String str5 = "#第一章\t#第二章\t#第三章";
        String[] split = pattern.split(str, -1);
        String[] split2 = pattern.split(str2, -1);
        String[] split3 = pattern.split(str3, -1);
        String[] split4 = pattern.split(str4, -1);
        String[] split5 = pattern.split(str5, -1);
        System.out.println("str数组的长度是:"+split.length);
        System.out.println("str2数组的长度是:"+split2.length);
        System.out.println("str3数组的长度是:"+split2.length);
        System.out.println("str4数组的长度是:"+split4.length);
        System.out.println("str5数组的长度是:"+split5.length);
    
    }
    

    运行结果

    str数组的长度是:4
    str2数组的长度是:4
    str3数组的长度是:4
    str4数组的长度是:2
    str5数组的长度是:2
    

    结论:除了字符串开头是行首,\r,\n,\r\n后面都可以当成行首

    $表示匹配字符串结束的地方,开启多行模式后,每一行都相当于一个字符串

    \r,\n,\r\n前面,和字符串最末尾都可以当成行尾被匹配到

    @Test
    public void demo3(){
        Pattern pattern =Pattern.compile("章$",Pattern.MULTILINE);
        String str = "#第一章\r\n#第二章\r\n#第三章";
        String[] split = pattern.split(str, -1);
        System.out.println("数组的长度是:"+split.length);
        for (int i = 0; i < split.length; i++) {
            System.out.print(split[i]);
        }
    }
    

    运行结果

    数组的长度是:4
    #第一
    #第二
    #第三
    

    学以致用

    写这么多不是白写的,真正使用的地方到了,也是我研究正则表达式一天的目的:整理md文档

    读写文件用到io流,这里推荐hutool工具包,方便快捷,先导入依赖

    <dependency>
        <groupId>cn.hutool</groupId>
        <artifactId>hutool-all</artifactId>
        <version>5.5.4</version>
    </dependency>
    

    代码:

        /**
         *
         * @param src  文件的来源
         * @param dest  文件目的地
         */
        public void mdTitleClean(String src,String dest){
            //默认UTF-8编码,可以在构造中传入第二个参数做为编码
            //输入流:将md文档一次性读进内存,返回一个String
            FileReader fileReader = new FileReader(src);
            String result = fileReader.readString();
    
            StringBuilder sb=new StringBuilder();
            //输出流,将字符串打印到文件中,该流使用完会自动关闭
            FileWriter writer = new FileWriter(dest);
    
            //md标题一共有6级,#空格后面写标题,我们想匹配到这个位置,所以是(?=(^#{1,6}\s+))
            Pattern p =Pattern.compile("^\\r?\\n(?=(^#{1,6}\\s+))",Pattern.MULTILINE);
            String[] split = p.split(result);
            for (int i = 0; i <split.length ; i++) {
                if (split[i].equals("")){
                    continue;
                }
                //先清除字符串前后的所有空格,空行,再加4个\r\n,相当于每个标题之间空三行
                sb.append(split[i].trim()).append("\r\n\r\n\r\n\r\n");
            }
            writer.write(sb.toString());
            System.out.println(sb.toString());
        }
    

    代码不难,只需要解释两行

    Pattern p =Pattern.compile("\r?\n(?=(#{1,6}\s+))",Pattern.MULTILINE);

    用到了前面讲的零宽断言字符边界
    在这里插入图片描述
    ^\r?\n表示字符串开头是换行符
    (?=(^#{1,6}\s+)) 表示匹配开头是# ,## ,### 的位置,即一级标题-六级标题
    最终的效果是以一级标题-六级标题前面的\r\n作为分隔符,把整个文档按照标题进行隔开。在这里插入图片描述
    sb.append(split[i].trim()).append("\r\n\r\n\r\n\r\n");

    隔开之后先清除前后空格,再拼接4个\r\n(统一格式),表示每个标题之间空三行

    最终效果图在这里插入图片描述
    以后写md文档就不用太关注格式了,写完用代码整理一下即可,注意在文档中使用#时,不要放在开头就行了。

    补充一点中文标点符号替换成英文的,要使用io流,记得导hutool工具包依赖

    /**
     * 英文标点符号替换成中文的
     *
     * @param str
     * @return
     */
    public String punctuationMarksAlter(String str) {
        str = str.replaceAll("(", "(")
                .replaceAll(")", ")")
                .replaceAll(";", ";")
                .replaceAll("'", "'")
                .replaceAll("'", "'")
                .replaceAll(""", "\"")
                .replaceAll(""", "\"")
                .replaceAll(":", ":")
                .replaceAll("?", "?")
                .replaceAll("[", "[")
                .replaceAll("]", "]")
                .replaceAll("!", "!")
                .replaceAll(".", ".")
                .replaceAll(",", ",");
        return str;
    }
    
    /**
     *
     * @param src  文件的来源
     * @param dest  文件目的地
     */
    public void mdClean(String src,String dest){
        //默认UTF-8编码,可以在构造中传入第二个参数做为编码
        FileReader fileReader = new FileReader(src);
        String result = fileReader.readString();
    
        StringBuilder sb=new StringBuilder();
        FileWriter writer = new FileWriter(dest);
    
        //md标题一共有6级,#空格后面写标题内容,我们想匹配到这个位置,所以是(?=(^#{1,6}\s+))
        Pattern p =Pattern.compile("^\\r?\\n(?=(^#{1,6}\\s+))",Pattern.MULTILINE);
        String[] split = p.split(result);
        for (int i = 0; i <split.length ; i++) {
            if (split[i].equals("")){
                continue;
            }
            //先清除字符串前后的所有空格,空行,再加4个\r\n,相当于每个标题之间空三行
            sb.append(split[i].trim()).append("\r\n\r\n\r\n\r\n");
        }
        //中文标点换成英文的
        String string = this.punctuationMarksAlter(sb.toString());
        writer.write(string);
    }
    

    逻辑可以自行完善
    如果把文档看成一个String字符串,那么就可以写java代码来自动整理md文档的格式了,而不用手动调格式,节约时间精力,更多的时间就可以花在学习上。

    split讲解到此为此,希望有所收获~
    上篇正则表达式的笔记我已经写好了,但是md图片粘贴在csdn上太麻烦,有时间再弄了。没有学过正则表达式的去b站看,一个半小时应该可以看完,要看请点这里

    从圣诞中午12点研究现在的时间是:2020年12月26日01:34:52,虽累也值得


    2020年12月28日19:34:21 开始学习jvm中篇[来自b站尚硅谷免费视频]
    自从学了正则表达式之后,可以很快速地替换文本
    比如下面是笔记的标题

    第十八章:Class文件结构
    
    01-JVM中篇内容概述
    
    02-字节码文件的跨平台性
    03-了解Java的前端编译器
    04-透过亨节码看代码执行细节举例1
    05-话过字节码看代码执行细节举例2
    06-透过字节码看代码执行细节举例3
    07-解读Class文件的三种方式
    08-Class文件本质和内部数据类型
    09-Class文件内部结构概述
    10-字节码数据保存到excel中的操作
    11-Class文件的标识:魔数
    12-Class文件版本号
    
    13-常量池概述
    14-常量池计数器
    15-常量池表中的字面量和符号引用
    16-解析得到常量池中所有的常量
    17-常量池表数据的解读1
    18-常量池表数据的解读2
    19-常量池表项数据的总结
    20-访问标识
    21-类索引、父类索引、接口索引集合
    22-字段表集合的整体理解
    23-字段表数据的解读
    24-方法表集合的整体理解
    25-方法表数据的解读
    26-屈性表集合的整理理解
    27-方法中Code属性的解读
    28-LineNumberTable和LocalVariableTable属性的解读
    29-SourceFile属性的解读
    30-Class文件结构的小结
    31-javac -g操作的说明
    32-javap主要参数的使用
    33-javap解析得到的文件结构的解读
    34-javap使用小结
    
    第十九章:字节码指令集与解析举例
    
    35-字节码指令集的概述
    36-指令与数据类型的关系及指令分类
    37-加载与存储指令概述
    38-再谈操作数栈与局部变量表
    39-局部变量压栈指令
    40-常量入栈指令
    41-出栈装入局部变量表指令
    42-算术指令及举例
    43-算法指令再举例
    44-彻底搞定++运算符
    45-比较指令的说明
    46-宽化类型转换
    
    47-窄化类型转换
    48-创建类和数组实例的指令
    49-字段访问指令
    50-数组操作指令
    51-类型检查指令
    52-方法调用指令
    53-方法返回指令
    54-操作数栈管理指令
    55-比较指令
    56-条件跳转指令
    57-比较条件跳转指令
    58-多条件分支跳转指令
    
    59-无条件跳转指令
    60-抛出异常指令
    61-异常处理与异常表
    62-同步控制指令
    
    第二十章:类的加载过程详解
    
    63-类的生命周期概述
    64-加载完成的操作及二进制的获取方式
    65-类模型与Class实例的位置
    66-链接之验证环节
    67-链接之准备环节
    68-链接之解析环节
    69-初始化过程与类初始化方法
    70-初始化阶段赋值与准备阶段赋值的对比
    71-类初始化方法clinit(的线程安全性
    72-何为类的主动使用和被动使用
    73-类的主动使用1
    74-类的主动使用2
    
    75-类的主动使用3
    76-类的主动使用4
    77-类的被动使用
    78-类的使用介绍
    79-类的卸载相关问题
    
    第二十一章:再谈类的加载器
    
    80-类加载器的概述
    81-命名空间与类的唯一性
    82-类的加载器的分类
    83-引导类加载器的说明
    84-扩展类加载器的说明
    85-系统类加载器的说明
    86-用户自定义类加载器的说明
    87-测试不同类使用的类加载器
    88-ClassLoader与Launcher的初步剖析
    89-ClassLoader的源码解析1
    90-ClassLoader的源码解析2
    91-ClassLoader子类的结构剖析
    
    91-ClassLoader子类的结构剖析
    92-双亲委派机制的优势与劣势
    93-三次双亲委派机制的破坏
    94-热替换的代码实现
    95-沙箱安全机制
    96-自定义类加载器的好处和应用场景
    97-自定义类加载器的代码实现
    98-Java9的新特性
    

    我们想要在每一行的前面加个#,意思是一级标题,就不用自己手动加了,使用正则表达式轻而易举的事
    在这里插入图片描述
    效果图
    在这里插入图片描述
    代码:用之前的代码随便改了下
    主要是正则表达式的匹配规则
    分隔符是(\r?\n)(?=[\d第])
    使用hutool工具包只是为了省几行代码,其实可以用传统io流,就不用导包了

    import cn.hutool.core.io.file.FileReader;
    import cn.hutool.core.io.file.FileWriter;
    import org.junit.Test;
    
    import java.util.Arrays;
    import java.util.Scanner;
    import java.util.regex.Pattern;
    
    public class Test2 {
        public static void main(String[] args) {
    //        String src ="D:\\太阳路\\正则表达式\\正则表达式.md";
            //String dest ="D:\\workspace\\jvm\\chapter05\\src\\main\\java\\c.md";
            Scanner scanner = new Scanner(System.in);
            System.out.println("请输入文件的全路径:");
            String src = scanner.next();
            System.out.println("请输入文件的保存路径:");
            String dest = scanner.next();
            new Test2().mdClean(src,dest);
        }
        /**
         * 英文标点符号替换成中文的
         *
         * @param str
         * @return
         */
        public String punctuationMarksAlter(String str) {
            str = str.replaceAll("(", "(")
                    .replaceAll(")", ")")
                    .replaceAll(";", ";")
                    .replaceAll("‘", "'")
                    .replaceAll("’", "'")
                    .replaceAll("“", "\"")
                    .replaceAll("”", "\"")
                    .replaceAll(":", ":")
                    .replaceAll("?", "?")
                    .replaceAll("【", "[")
                    .replaceAll("】", "]")
                    .replaceAll("!", "!")
                    .replaceAll(".", ".")
                    .replaceAll(",", ",");
            System.out.println("标点符号替换完毕");
            return str;
        }
    
        /**
         *
         * @param src  文件的来源
         * @param dest  文件目的地
         */
        public void mdClean(String src,String dest){
            //默认UTF-8编码,可以在构造中传入第二个参数做为编码
            //hutool工具包,读取文件到String中
            FileReader fileReader = new FileReader(src);
            String result = fileReader.readString();
    
            //输出流
            StringBuilder sb=new StringBuilder();
            FileWriter writer = new FileWriter(dest);
    
            //md标题一共有6级,#空格后面写标题内容,我们想匹配到这个位置,所以是(?=(^#{1,6}\s+))
    //            Pattern p =Pattern.compile("^\\r?\\n(?=(^#{1,6}\\s+))",Pattern.MULTILINE);
                Pattern p =Pattern.compile("(\\r?\\n)(?=[\\d第])",Pattern.MULTILINE);
            String[] split = p.split(result);
            for (int i = 0; i <split.length ; i++) {
                if (split[i].equals("")){
                    //如果是空字符串,什么都不处理
                    continue;
                }
                //先清除字符串前后的所有空格,空行,再加4个\r\n,相当于每个标题之间空三行
                if (i!=split.length-1){
                    sb.append("# ").append(split[i].trim()).append("\r\n\r\n\r\n\r\n");
                }else {
                    //文章最后一行不需要空空行
                    sb.append("# ").append(split[i].trim());
                }
            }
            System.out.println("文档标题的格式整理完毕!");
            //中文标点换成英文的
            String string = this.punctuationMarksAlter(sb.toString());
            writer.write(string);
        }
    }
    
    
    展开全文
  • Split方法: 以下程序例子实现了split和整数字符串互转的用法。。。 [removed] function evil() { var toint=parseInt(“123”);//字符串转换成整形 var intvalue=123; var tostr=intvalue.toString();//类型转换成...
  • java中String类的intern、split方法的详细讲解。
  • 主要介绍了java的split方法使用示例,需要的朋友可以参考下
  • JAVA中String的split方法

    2020-06-18 15:40:48
    Java 中 String 的 split 方法可以将字符串根据指定的间隔进行切割,例如字符串 str = “1,23,4,5” 经过 str.split(",") 切割后得到的返回值是一个字符串数组 String[] = [1, 23, 4, , 5],这种处理方式可以适配...

    我的个人网站:
    http://riun.xyz


    以下源码版本:JDK1.8

    简介

    Java 中 String 的 split 方法可以将字符串根据指定的间隔进行切割,例如字符串 str = “1,23,4,5” 经过 str.split(",") 切割后得到的返回值是一个字符串数组 String[] = [1, 23, 4, , 5],这种处理方式可以适配大多数场景。

    问题

    今天写一个读取csv文件的时候,发现一个小问题。【csv,一种文本文件格式,每行中的数据以逗号分隔,在windows平台可以使用excel打开,打开后和普通excel显示并无差别】

    我处理的文件中存在这样的一行数据:

    ,,,,f02e843b-a328-4023-bbbd-7ce075a29bef,,,2.00422E+19,,3000,12,6,2020/10/22,1,245.05,56.34,0,301.39,245.05,56.34,0,0,301.39,0,0,0,0,,0,0,NULL,,,,,,,,,,,,,,,,,,,,
    

    使用BufferedReader.readLine()去读取一行,然后用逗号分隔:str.split(","),最后发现拿到 的字符串数组中,前面的空串数据存在,后面的空串数据都消失了。即split切割后剩下的数据:

    ,,,,f02e843b-a328-4023-bbbd-7ce075a29bef,,,2.00422E+19,,3000,12,6,2020/10/22,1,245.05,56.34,0,301.39,245.05,56.34,0,0,301.39,0,0,0,0,,0,0,NULL
    

    (后面的空串没了,到NULL结束了)

    由于csv文件中,每列数据都对应的有key,例如第一列为id,第二列为name,等等,所以即使是空串也必须存在,不能丢失。

    分析

    在看过split源码后发现,String的split方法有两个重载方法:public String[] split(String regex)public String[] split(String regex, int limit)

    而调用split(String regex)方法时,内部是直接调用的 split(regex, 0),如下图:
    在这里插入图片描述

    split(regex, 0)中,进行字符串的切割。

    源码里,切割后又做了其他事情,如下:

    int resultSize = list.size();
    if (limit == 0) {
        while (resultSize > 0 && list.get(resultSize - 1).length() == 0) {
            resultSize--;
        }
    }
    

    其中list储存结果数据。

    如果我们使用split(regex)的话,会调用split(regex,0)那么就是说我们不传入limit参数,limit默认为0。所以这里会进入if语句。

    进入后,就开始从后向前循环(resultSize为结果元素长度,所以是从后向前),如果是空串(length==0),就清除掉此数据(resultSize–)。

    注意由于这里是 && 符号连接,所以当循环时遇到不为空串,就立即跳出while了。所以此过程清除掉的数据是结尾处的所有空串。

    ,,,a,bss,cas,,fq,try,,h,,,, 这个字符串使用split(",")切割后,留下的数据是,,,a,bss,cas,,fq,try,,h,在从后向前循环时碰到第一个不为空串的数据 h 就会停止,然后返回。

    而我们想要让split不清除数据,拿到分隔后的原始数据时怎么办呢?看代码知道应该传入limit,让limit!=0,这样就不会进入if语句,不会执行这些清除空串数据的代码。那么limit的值应该传入什么呢?下面进行几个小实验:

    # 1、
    String str = ",,,a,bss,cas,,fq,try,,h,,,,";
    String[] split2 = str.split(",", 1); # limit为1
    System.out.println(Arrays.toString(split2));
    System.out.println("长度为"+split2.length);
    
    >[,,,a,bss,cas,,fq,try,,h,,,,] # 此处是一个串
    >长度为1
        
    # 2、
    String str = ",,,a,bss,cas,,fq,try,,h,,,,";
    String[] split2 = str.split(",", 5); # limit为5
    System.out.println(Arrays.toString(split2));
    System.out.println("长度为"+split2.length);
    
    >[, , , a, bss,cas,,fq,try,,h,,,,] # 此处是5个串,分别为:空串,空串,空串,a,bss,cas,,fq,try,,h,,,,
    >长度为5
        
    # 3、
    String str = ",,,a,bss,cas,,fq,try,,h,,,,";
    String[] split2 = str.split(",", Integer.MAX_VALUE); # limit为Integer.MAX_VALUE
    System.out.println(Arrays.toString(split2));
    System.out.println("长度为"+split2.length);
    
    >[, , , a, bss, cas, , fq, try, , h, , , , ] # 此处将所有串都拿到了,没有清除数据。
    >长度为15
    

    当传入负数时,偶尔会运行成功,大多数情况下,会报以下错误:
    在这里插入图片描述

    结论

    我们可以分析出,传入limit为正数时,split就不会帮我们清除掉它认为无用的数据,而是将limit作为结果长度的最大值进行切割。而当传入limit为0时,split会帮我们切割掉后面的空串。所以limit的含义是切割后结果的阀值(最大值),帮我们限制切割后结果的长度,limit为0时就走JAVA自己定的规则(清除结尾处的空串)。

    所以当我们的使用场景需要全部数据时,要使用两个参数的split方法手动传入limit,建议limit的值为Integer.MAX_VALUE,这样可以在不知道结果长度的情况下保证结果正确。

    split(regex,limit)方法的完整结构大概可分三段解释,如图:
    在这里插入图片描述

    展开全文
  • java中的split方法

    万次阅读 2018-12-04 08:23:26
    split 方法 将一个字符串分割为子字符串,然后将结果作为字符串数组返回。 stringObj.split([separator,[limit]]) stringObj  必选项。要被分解的 String 对象或文字。该对象不会被 split 方法修改。 separator...

    java.lang.string.split

    split 方法
    将一个字符串分割为子字符串,然后将结果作为字符串数组返回。

    stringObj.split([separator,[limit]])

    stringObj 
    必选项。要被分解的 String 对象或文字。该对象不会被 split 方法修改。

    separator 
    可选项。字符串或 正则表达式 对象,它标识了分隔字符串时使用的是一个还是多个字符。如果忽
    略该选项,返回包含整个字符串的单一元素数组。 

    limit
    可选项。该值用来限制返回数组中的元素个数。

    说明:
    split 方法的结果是一个字符串数组,在 stingObj 中每个出现 separator 的位置都要进行分解
    。separator 不作为任何数组元素的部分返回。


    示例1:
    public class SplitDemo {
        
         public static String[] ss = new String[20];

         public SplitDemo() {

             String s = "The rain in Spain falls mainly in the plain.";
             // 在每个空格字符处进行分解。
             ss = s.split(" ");
         }

         public static void main(String[] args) {

             SplitDemo demo = new SplitDemo();
             for (int i = 0; i < ss.length; i++)
                 System.out.println(ss[i]);
         }

    }

    程序结果:
    The
    rain
    in
    Spain
    falls
    mainly
    in
    the
    plain.


    示例2:
    public class SplitDemo {

         public static String[] ss = new String[20];

         public SplitDemo() {

             String s = "The rain in Spain falls mainly in the plain.";
             // 在每个空格字符处进行分解。
             ss = s.split(" ", 2);
         }

         public static void main(String[] args) {
             SplitDemo demo = new SplitDemo();
             for (int i = 0; i < ss.length; i++)
                 System.out.println(ss[i]);
         }

    }

    程序结果:
    The
    rain in Spain falls mainly in the plain.


    示例3:
    public class SplitDemo {

         public static String[] ss = new String[20];

         public SplitDemo() {

             String s = "The rain in Spain falls mainly in the plain.";
             // 在每个空格字符处进行分解。
             ss = s.split(" ", 20);
         }

         public static void main(String[] args) {
             SplitDemo demo = new SplitDemo();
             for (int i = 0; i < ss.length; i++)
                 System.out.println(ss[i]);
         }

    }

    程序结果:
    The
    rain
    in
    Spain
    falls
    mainly
    in
    the
    plain.


    示例4:
    public class SplitDemo {

         public static void main(String[] args) {

             String value = "192.168.128.33";
             String[] names = value.split(".");
             for (int i = 0; i < names.length; i++) {
                 System.out.println(names[i]);
             }

         }
    }

    运行结果: 

    对,没看错!没有任何输出! 
    让我们来看看 split 方法的方法签名吧:

    public string[] split(string regex) 
    这里的参数的名称是 regex ,也就是 regular expression (正则表达式)。这个参数并不是一个简单的分割用的字符,而是一个正则表达式,看了 split 方法的实现代码就更坚定了我们的信心: 

    public string[] split(string regex, int limit) { 
    return pattern.compile(regex).split(this, limit); 

    split 的实现直接调用的 matcher 类的 split 的方法。读者已经知道,“ . ”在正则表达式中有特殊的含义,因此我们使用的时候必须进行转义。 
    只要将
    String[] names = value.split(".");
    改为
    String[] names = value.split("//.");
    就可以了。

    输出结果:
    192
    168
    128
    33 


    再加一点儿补充(这是Java帮助文档中的,更清晰一些):

    public String[] split(String regex,int limit)根据匹配给定的正则表达式来拆分此字符串。 
    此方法返回的数组包含此字符串的每个子字符串,这些子字符串由另一个匹配给定的表达式的子字符串终止或由字符串结束来终止。数组中的子字符串按它们在此字符串中的顺序排列。如果表达式不匹配输入的任何部分,则结果数组只具有一个元素,即此字符串。 

    limit 参数控制模式应用的次数,因此影响结果数组的长度。如果该限制 n 大于 0,则模式将被最多应用 n - 1 次,数组的长度将不会大于 n,而且数组的最后项将包含超出最后匹配的定界符的所有输入。如果 n 为非正,则模式将被应用尽可能多的次数,而且数组可以是任意长度。如果 n 为零,则模式将被应用尽可能多的次数,数组可有任何长度,并且结尾空字符串将被丢弃。 

    例如,字符串 "boo:and:foo" 使用这些参数可生成下列结果: 

    Regex      Limit                结果 

       :          2             { "boo", "and:foo" } 
       :          5             { "boo", "and", "foo" } 
       :          -2            { "boo", "and", "foo" } 
       o          5             { "b", "", ":and:f", "", "" } 
       o          -2            { "b", "", ":and:f", "", "" } 
       o          0             { "b", "", ":and:f" } 

    这种形式的方法调用 str.split(regex, n) 产生与以下表达式完全相同的结果: 

    Pattern.compile(regex).split(str, n) 

    参数:
    regex - 定界正则表达式
    limit - 结果阈值,如上所述 
    返回:
    字符串数组,根据给定正则表达式的匹配来拆分此字符串,从而生成此数组 
    抛出: 
    PatternSyntaxException - 如果正则表达式的语法无效
    从以下版本开始: 
    1.4 


    public String[] split(String regex)根据给定的正则表达式的匹配来拆分此字符串。 
    该方法的作用就像是使用给定的表达式和限制参数 0 来调用两参数 split 方法。因此,结果数组中不包括结尾空字符串。 

    例如,字符串 "boo:and:foo" 产生带有下面这些表达式的结果: 

    Regex                 结果 
       :            { "boo", "and", "foo" } 
       o            { "b", "", ":and:f" } 

    参数:
    regex - 定界正则表达式 
    返回:
    字符串数组,根据给定正则表达式的匹配来拆分此字符串,从而生成此数组。 
    抛出: 
    PatternSyntaxException - 如果正则表达式的语法无效 
    --------------------- 
    作者:daxiang_zhang 
    来源:CSDN 
    原文:https://blog.csdn.net/daxiang_zhang/article/details/2149896 
    版权声明:本文为博主原创文章,转载请附上博文链接!

    展开全文
  • JavaScript split 方法 split 方法用于将字符串分割为字符串数组并返回该数组。其语法如下: 代码如下: str_object.split(separator, limit) 参数说明: 参数 说明 str_object 要操作的字符串(对象) ...
  • split定义和用法 split() 方法用于把一个字符串分割成字符串数组。 语法 stringObject.split(separator, howmany)参数 描述 separator 必需。字符串或正则表达式,从该参数指定的地方分割 stringObject。 howmany 可...
  • JAVA中字符串split方法的探究

    千次阅读 2019-07-04 20:43:39
    今日在使用split分割字符串时突然想到一种情况,如下: String str="aaaaaaaab"; String arr[]=str.split("aa"); 问,arr数组的长度是多少? 那如果str为”baaaaaaaa”呢 String str="baaaaaaaa"; 如果str=”...

    今天在使用split分割字符串时突然想到一种情况,如下:

    String str="aaaaaaaab";
    String arr[]=str.split("aa");
    

    问,arr数组的长度是多少?
    那如果str为”baaaaaaaa”呢

    	String str="baaaaaaaa";
    

    如果str=”aaaaaaaab”呢

    String str="aaaaaaaab";
    

    如果str=”baaaaaaaab”呢

    String str="baaaaaaaab";
    

    好,我们先在程序中验证一下:

    public class Test {
    
    	public static void main(String[] args) {
    		String str="aaaaaaaa";
    		String [] arr=str.split("aa");
    		System.out.println("字符串aaaaaaaa分割的数组长度为:"+arr.length);
    		
    		str="baaaaaaaa";
    		arr=str.split("aa");
    		System.out.println("字符串baaaaaaaa分割的数组长度为:"+arr.length);
    		
    		str="aaaaaaaab";
    		arr=str.split("aa");
    		System.out.println("字符串aaaaaaaab分割的数组长度为:"+arr.length);
    		
    		str="baaaaaaaab";
    		arr=str.split("aa");
    		System.out.println("字符串baaaaaaaab分割的数组长度为:"+arr.length);
    
    	}
    }
    

    运行以上代码输出结果
    在这里插入图片描述
    看到结果的你是不是有点小小的惊讶,如果有的话那就继续往下看。
    通过split方法查看源码可知又调用了split(regex, 0)方法并且传入一个0:

      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) {
                    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);
        }
    

    有其中关系可知最终会执行 Pattern.compile(regex).split(this, limit)这一段代码,基础往下扒代码:

      public String[] split(CharSequence input, int limit) {
            int index = 0;
            boolean matchLimited = limit > 0;
            ArrayList<String> matchList = new ArrayList<>();
            Matcher m = matcher(input);
    
            // Add segments before each match found
            while(m.find()) {
                if (!matchLimited || matchList.size() < limit - 1) {
                    if (index == 0 && index == m.start() && m.start() == m.end()) {
                        // no empty leading substring included for zero-width match
                        // at the beginning of the input char sequence.
                        continue;
                    }
                    String match = input.subSequence(index, m.start()).toString();
                    matchList.add(match);
                    index = m.end();
                } else if (matchList.size() == limit - 1) { // last one
                    String match = input.subSequence(index,
                                                     input.length()).toString();
                    matchList.add(match);
                    index = m.end();
                }
            }
    
            // If no match was found, return this
            if (index == 0)
                return new String[] {input.toString()};
    
            // Add remaining segment
            if (!matchLimited || matchList.size() < limit)
                matchList.add(input.subSequence(index, input.length()).toString());
    
            // Construct result
            int resultSize = matchList.size();
            if (limit == 0)
                while (resultSize > 0 && matchList.get(resultSize-1).equals(""))
                    resultSize--;
            String[] result = new String[resultSize];
            return matchList.subList(0, resultSize).toArray(result);
        }
    

    通过代码我们可以发现最终matchList集合中会有值,不过都是空值,然后在

      while (resultSize > 0 && matchList.get(resultSize-1).equals(""))
                    resultSize--;
    

    这一段代码中,首先判断最后一个是不是空,如果没有值的话就减一位,依次类推,所以看到这大家对以上程序出现的结果是不是就不奇怪了。
    所以我们可以大胆的总结一下,使用split方法分割字符串,如果最后几位是空的话,会将空的位置去掉。

    加入我的行列:

    (嘿嘿嘿,点击这里关于我哦,分享小知识):https://www.jianshu.com/p/7d19f0df5b6b

    展开全文
  • 主要介绍了Java正则表达式之split()方法,结合实例形式较为详细的分析了split方法的功能、使用方法及相关注意事项,需要的朋友可以参考下
  • 本文实例讲述了js使用split函数按照多个字符对字符...下面的代码可以通过js split方法对字符串按照逗号分割 var mystring = "a,b,c,d,e"; var myarray = mystring.split(","); 如果有这样一个字符串:”jb51.net,goo
  • java split方法注意事项

    千次阅读 2018-09-27 14:11:55
    分割数据时,会使用到split方法,分割后有时会遇到问题。例如,是否以分割 符结尾时,分割出来的字符数组长度是不一样的。 一 , java split简单用法 public class SplitTest {  public static void main(String...
  • 介绍的是利用Javascript中的split方法来实现彩色文字背景效果,实现后的效果很好,有需要的可以参考借鉴。
  • java中split方法 思考下列代码的执行结果 public static void main(String[] args) { // TODO Auto-generated method stub String str1 = "a,b,c,,,a"; String str2 = "a,b,c,,,"; String str3 =...
  • Java String的split方法总结

    万次阅读 多人点赞 2019-03-01 17:42:28
    String的split()方法用于按传入的字符或字符串对String进行拆分,返回拆分之后的数组。 1、一般用法 用一般的字符,例如@或,等符号做分隔符时: String address="上海@上海市@闵行区@吴中路"; String...
  • String的split方法的使用

    万次阅读 多人点赞 2018-04-25 23:05:46
    java中String类中的split方法的使用
  • Java使用split方法返回String数组

    千次阅读 2020-08-11 17:01:39
    Java使用split方法返回String数组 题目描述 将一个英文语句以单词为单位逆序排放。例如“I am a boy”,逆序排放后为“boy a am I” 所有单词之间用一个空格隔开,语句中除了英文字母外,不再包含其他字符 输入:I ...
  • JavaScript中String的split方法详解

    千次阅读 2019-03-06 11:06:09
    String.prototype.split()方法通过传入的参数符号,将一个字符串对象分割成一个字符串数组,这个传入的参数符号决定着字符串在什么位置进行分割。 var str = 'The quick brown fox jumps over the lazy dog.'; var ...
  • String 中 split 方法的效率问题

    千次阅读 2018-11-11 22:36:09
    问:String 中 split 方法使用时有什么效率问题吗? 答:String 的 split 分割字符串函数我们一般会如下方式使用。 String[] arr = "a,b,c".split(","); 上面代码非常简洁, 也没什么问题。不过...
  • js的split方法的用法

    千次阅读 2019-02-16 16:19:00
    strArray = str.split(","); //分割 for (i=0; i; i++)  {  document.write(strArray[i]+" ");  }    转载于:https://my.oschina.net/jirglt/blog/3010887
  • js 字符串切割 split方法 遍历map方法

    千次阅读 2018-11-19 10:23:42
    split:  ...//split方法中传递的参数取决于你想获得的数组数据,str.split('')方法返回数组 map:  map() 方法返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值。 array.map(f
  • String的split方法返回的是一个String数组 意为 按照 “关键字” 分割 String字符串 注意的是: 分割之后的数组,会自动省略后面的空字符串,而不会省略前面的空字符串 代码: @Test public void test() { // a...
  • split方法后面为空的问题

    千次阅读 2019-12-26 20:37:28
    split后面为空的问题 String[] split = str.split(",...二、如果不想舍弃后面为空的情况,需要使用方法str.split(",", -1);,没有-1的参数时,默认为0; 以下是实验: 1、数据规则时 String str = "0,1,2,3,4,5,6,7,8...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 546,376
精华内容 218,550
关键字:

split方法