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()]);
}
}