liujijiang

java学习笔记 --13-- 字符串

2020.03.31

字符串

String对象是不可变的
当对String对象使用方法时,Java复制一份String对象的引用给方法用,方法结束后复制的引用消失,方法返回的结果是一个新的对象的引用,所以原String对象没有改变,这是我们想要的,希望一个方法返回值而不是改变自己

重载‘+’ 和StringBuilder

String对象是只读的,所有的String对象的引用都不能改变String对象

package com.company;

/**
 * @ClassName Test
 * @Description
 * @Auther liuxiansen
 * @Date 2020/3/29 8:55 上午
 **/
public class Test{


    public static void main(String [] args) throws Exception {

        String string = "123";
        String string1 = string + "456" + "789";
        System.out.println(string1);
    }

}


这段代码的工作流程:新建一个对象将string与“123”相连,然后再新建一个对象将上个对象与“789”相连,以此类推
过程中产生了很多的没有的对象比如string+“123”
但其实:Java自动调用了StringBuilder类完成这个工作,使用StringBuilder的append方法可以将字符串拼接,大大提高性能

如果字符串小,使用String重载的+
如果字符串长,使用StringBuilder

StringBuilder是JavaSE5引入的,之前是StringBuffer

package com.company;

/**
 * @ClassName Test
 * @Description
 * @Auther liuxiansen
 * @Date 2020/3/29 8:55 上午
 **/
public class Test{


    public static void main(String [] args) throws Exception {

        String string = "Red arm forever";

        //字符串长度
        System.out.println(string.length());

        //参数位置的字符
        System.out.println(string.charAt(0));

        //返回字符数组
        char [] chars = string.toCharArray();
        System.out.println(chars[1]);

        //字符串与参数是否相等,值比较
        System.out.println(string.equals("red"));

        //按照字典顺序比较,返回正,负,0
        System.out.println(string.compareTo("red"));

        //字符串是否包含参数
        System.out.println(string.contains("red"));

        //如果字符串内容与参数内容完全一致返回true
        System.out.println(string.contentEquals("red"));

        //忽略大小写比较内容是否完全一样
        System.out.println(string.equalsIgnoreCase("red"));

        //是否以参数开头
        System.out.println(string.startsWith("Red"));

        //是否以参数截尾
        System.out.println(string.endsWith("er"));

        //第一个参数字符的位置
        System.out.println(string.indexOf('e'));

        //最后一个参数字符的位置
        System.out.println(string.lastIndexOf('e'));

        //子串,一个参数:起始索引,两个参数:起始和终止索引
        System.out.println(string.substring(0));
        System.out.println(string.substring(4,8));

        //连接参数字符串
        System.out.println(string.concat("!!!"));

        //第二个参数代替第一个参数
        System.out.println(string.replace("arm","arms"));

        //转为大写小写
        System.out.println(string.toUpperCase());
        System.out.println(string.toLowerCase());
        
        //除去字符串开始之前和结尾之后的空格
        System.out.println(string.trim());
        
        //把参数转为字符串
        System.out.println(String.valueOf(1));
    }

}


字符串的基本操作

正则表达式

提供了一种通用的字符串操作,匹配,选择,编辑,验证
java中 \ \ 表示插入一个正则表达式的\,也就是转义,+在java中表示将两个字符串相接,如果想让‘+’单纯的表示‘+'的意思就需要转义,\ +
比如:
表示一个数字:\d
插入一个普通\:\ \ \
换行制表符:\n \t


+:表示有一个或多个之前的表达式
?:表示可能存在
():表示将表达式分组
|:表示或
所以 -?\ \d+ 表示可能有一个-号,后面有一个或多个数字

System.out.println("+1234".matches("\\+?\\d+"));

String的matches方法:检查一个字符串是否匹配正则表达式

String方法split:将字符串从正则表达式匹配的地方切开

package com.company;

/**
 * @ClassName Test
 * @Description
 * @Auther liuxiansen
 * @Date 2020/3/29 8:55 上午
 **/
public class Test{
    public static void main(String [] args) throws Exception {

        String str = "Red arm forever, the first time i lost " +
                " my best friend i think it was the end of the world";

        String [] strs = str.split(" ");
        for(String s : strs){
            System.out.println(s);
        }
        String[] strs1 = str.split("\\W+");
        for(String s : strs1){
            System.out.println(s);
        }
        String [] strs2 = str.split("\\w+");
        for(String s : strs2){
            System.out.println(s);
        }
    }

}


第一种:在空格处切开
\W+:大写的W表示非单词字符,所以不是字母的地方切开
\w+:小写的w表示单词字符,所以是字母的地方切开
split方法:结果中不包括正则表达式匹配的地方

replace中使用正则

package com.company;

/**
 * @ClassName Test
 * @Description
 * @Auther liuxiansen
 * @Date 2020/3/29 8:55 上午
 **/
public class Test{
    public static void main(String [] args) throws Exception {

        String str = "Red arm forever, the first time i lost " +
                " my best friend i think it was the end of the world";

        String str1 = str.replaceAll("t\\w+","***");
        System.out.println(str);
        System.out.println(str1);

    }

}


所有的t开头单词用**替换,不是单词一定要t开头,而是带t,it变为i
原来的字符串不变,返回一个新的对象的引用

常用的规则:

  • 字符
    • B:指定字符B
    • \xhh:十六进制
    • \t:制表符Tab
    • \n:换行符
    • \r:回车
    • \f:换页
    • \e:转义
  • 字符串
    • . :任意字符
    • [abc]:包含a,b,c的任意字符(和a|b|c相同)
    • [^abc]:出了a,b,c的任意字符
    • [a-zA-Z]:从a-z或从A-Z的任意字符
    • \s:空白符(空格,Tab,换行,换页,回车)
    • \S:非空白符
    • \d:数字
    • \D:非数字
    • \w:词符[a-zA-Z0-9]
    • \W:非词符
  • 逻辑操作符
    • XY:Y跟在X后面
    • X|Y:X或Y
    • (X):捕获组

量词

量词:描述了一个模式吸收文本的方式

  • 贪婪型:匹配到字符组后仍然匹配
  • 勉强型:匹配满足正则的最少字符,在贪婪型后加一个?
  • 占有型:防止回溯,用于正则表达式失控,在贪婪型后加一个+

贪婪型:

  • X?:一个或零个X
  • X*:零个或多个X
  • X+:一个或多个
  • X:恰好n个X
  • X{n,}:至少n个X
  • X{n,m}:至少n个,至多mge

CharSequence

接口,抽象出了字符序列的一般化定义,多数正则表达式接受CharSequence类型的参数

Pattern和Matcher

package com.company;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @ClassName Test
 * @Description
 * @Auther liuxiansen
 * @Date 2020/3/29 8:55 上午
 **/
public class Test{
    public static void main(String [] args) throws Exception {

        String str = "Red arm forever, the first time i lost " +
                " my best friend i think it was the end of the world";

        Pattern pattern = Pattern.compile("t\\w+");

        Matcher matcher = pattern.matcher(str);

        while (matcher.find()){
            System.out.println(matcher.group() + matcher.start() + matcher.end());
        }

    }

}


使用更强大的正则表达式
Pattern.compile输入正则表达式,返回一个Pattern对象的引用
Pattern.matcher方法接受待处理的字符串,返回一个Matcher对象的引用

  • matcher.find:如果匹配到返回true,可以传入一个参数表示搜寻起点
  • matcher.start:匹配到的第一个字符索引
  • matcher.end:最后一个字符索引

A(B( C))D

  • 0组:ABCD
  • 1组:BC
  • 2组:C

package com.company;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @ClassName Test
 * @Description
 * @Auther liuxiansen
 * @Date 2020/3/29 8:55 上午
 **/
public class Test{
    public static void main(String [] args) throws Exception {

        String str = "Red arm forever, the first time i lost " +
                " my best friend i think it was the end of the world";

        Pattern pattern = Pattern.compile("t?(i\\w+)");

        Matcher matcher = pattern.matcher(str);

        System.out.println(matcher.groupCount());


        while (matcher.find()){
            System.out.println(matcher.group(1));
            System.out.println(matcher.group() + matcher.start() + matcher.end());
        }

    }

}


groupCount:返回组数,第0组不算
matcher.group:返回第0组正则匹配到的内容
matcher.group(i):返回第i组正则匹配到的内容

Pattern标记

  • Pattern.compile方法可以接受两个参数,第一个参数是正则表达式,第二个参数是一个标记参数,可以调整匹配行为
  • Pattern.CASE_INSENSITIVE(?i):不考虑大小写
  • Pattern.MULTILINE(?m):多行模式下,^和$表示一行的开始和结尾,同时还表示字符串的开始和结尾
  • Pattern.COMMENTS(?x):空格符被忽略掉,以#开始的注释忽略

替换操作

package com.company;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @ClassName Test
 * @Description
 * @Auther liuxiansen
 * @Date 2020/3/29 8:55 上午
 **/
public class Test{
    public static void main(String [] args) throws Exception {

        String str = "Red arm forever, the first time i lost " +
                " my best friend i think it was the end of the world";

        Matcher matcher = Pattern.compile("\\w+").matcher(str);

        while (matcher.find()){
            System.out.println(matcher.group());
        }

        String reString =  matcher.replaceFirst("123");

        System.out.println(reString);

        StringBuffer s = new StringBuffer();

        while (matcher.find()){
            matcher.appendReplacement(s,matcher.group().toUpperCase());

            matcher.appendTail(s);

            System.out.println(s);
        }

    }

}


replaceFirst:替换第一个匹配到的
replaceAll:替换所有匹配到的
appendRepelacement:两个参数,StringBuffer和String,匹配到的字符串进行参数String处理,加到StringBuffer中
appendTail:匹配到的结果后面的字符串加到s中

reSet

传入一个字符串参数,对字符串进行匹配