12.Java中的字符串缓冲区和正则表达式

1、字符串缓冲区

1.1 概念

就是用来保存临时的字符数据的空间;

1.2 Java的字符串缓冲区类

StringBuffer:是线程安全的,效率相对比较低;如果在多线程环境下,对线程安全有要求,就要使用StringBuffer

StringBuilder:是线程不安全的,效率相对比较高;如果在单线程环境下,或者对线程安全没有要求,就可以使用StringBuilder

1.3 操作:缓冲区是一个容器,对容器的数据操作,一般都有四种操作

  • :表示向容器中添加数据
  • :表示从容器中移除数据
  • :表示修改容器中的数据
  • :表示从容器中获取数据

对于字符串缓冲区来说,开发中常用到的方法主要就是toString、append、insert、revers、substring和setLength这几个方法;

其他的用到的时候知道怎么查API文档就行了

2、正则表达式

2.1 概念

就是使用一些特殊符号组成的一种匹配规则,可以用来对字符串进行匹配的;

2.2 正则的写法

  • 一般字符

表示匹配自身;如:a,表示匹配的字符传的值只能是a;所有普通字符串,都可以看作是一个正则表达式,匹配的是它自身; 一般字符

  • 字符类

使用中括号[]和里面的内容组成,表示一个字符的取值范围;如:[a-z]:表示被匹配的字符的值可以是所有的小写字母; 字符类

  • 预定义字符

使用特殊符号或转义字符组成的表示特殊匹配范围的规则,如:. 表示匹配所有字符;\d表示匹配0-9的所有数字; 预定义字符

  • 边界符

表示匹配一些字符串的边界,如:^:表示匹配一行的开始;$:表示匹配一行的结束; 边界符

  • 数量词

前面必须跟一个规则,表示这个规则可以重复的次数;如:\d+:表示最少有一个数字;.?:表示最多有一个任意字符; 数量词

  • 运算符: 运算符

有的时候,希望可以调用前面已经定义好的规则,让调用的地方匹配的内容和前面一致,就可以使用组

  • 概念:就是使用小括号括起来的一段规则;后面调用是使用组出现的顺序的序号来调用的;
  • 调用的格式是\\组号
  • 在同一个语句中,后面的正则表达式也可以引用前面正则表达式中定义的规则,使用的格式是:$组号

2.3 常见应用

  • 匹配字符串
/**
需求:验证手机号码是否合法:

手机号码的规则:
1、号码是11位数字;
2、号码只能以1开头;
3、号码的第二位可以是:3,4,5,7,8;
4、从第三位开始后面的数字都可以是0到9的任意数字;
*/
public class Test1{
  public static boolean checkPhoneNum(String phone){
    return phone.matches("1[34578]\\d{9}");
  }
  
  public static void main(String[] args){
    String phone = "15888888888";
    System.out.println(checkPhoneNum(phone));
  }
}
  • 分割字符串
/**
需求:按重复的字符分隔字符串:”qwe##asdf####zx#######cv”;
*/
public class Test2{
  
  public static void main(String[] args){
    String str = "qwe##asdf####zx#######cv";
    String[] ss = str.split("#{2,}");
    for(int i=0; i<ss.length;i++){
      System.out.println(ss[i]);
    }
  }
}
  • 替换字符串
public class Test3{
  
    /**
    需求:替换字符串中重复的#为-:
    1、原字符串:”qwe##as#df####zx#######cv”;
    替换后:”qwe-as#df-zx-cv”;
    */
  public static void main(String[] args){
    String str = "qwe##as#df####zx#######cv";
    System.out.println(str);
		str = str.replaceAll("#{2,}","-");
    System.out.println(str);
  }
}



public class Test4{
  
  public static void main(String[] args){
    test1();
    test2();
  }
  
  /**
  1、原字符串:”qwe##asdfxxxxzx%%%%%cv”;

  替换后:”qwe-asdf-zx-cv”;
  */
  public static void test1(){
    String str = "qwe##asdfxxxxzx%%%%%cv";
    System.out.println(str);
		str = str.replaceAll("(.)\\1+","-");
    System.out.println(str);
  }
  
  /**
  2、原字符串:”qwe##asdfxxxxzx%%%%%cv”;
  替换后:”qwe#asdfxzx%cv”;
  */
  public static void test2(){
    String str = "qwe##asdfxxxxzx%%%%%cv";
    System.out.println(str);
    //在同一个语句中,非同一个正则表达式,在后面可以调用前面的正则表达式中的组  
		str = str.replaceAll("(.)\\1+","$1");
    System.out.println(str);
  }
}
  • 获取字符串中匹配的子串
public class Test3{
  
  public static void main(String[] args){
    String str = "张三:13233332323;李四:15666668888;王五:18288999988";
    String regex = "1[34578]\\d{9}";
    String[] strs =getRegexData(str,regex);
		for(int i=0; i<strs.length;i++){
      System.out.println(strs[i]);
    }
  }
  
  public static String[] getRegexData(String str,String regex){
     //1、通过正则规则和Pattern类的静态函数compile 创建Pattern类的实例对象:	Pattern  p = Pattern.compile(正则规则);
     Pattern  p = Pattern.compile(regex);
    //2、根据创建的Pattern对象和要匹配的字符串创建匹配器对象(Matcher类的实例对象);Matcher m = p.matcher(“匹配的字符串”);
     Matcher m = p.matcher(str);
    //3、通过匹配器对象的find方法判断是否有匹配对象:	boolean b = m.find();
    //如果有,使用group方法获取匹配的子串:	String str = m .group();
     List<String> list = new ArrayList<>();
     while(m.find()){
       list.add(m.group());
     }
    return list.toArray(new String[list.size()]);
  }
  
}