1.字符串
1.1字符串简介
字符串:是由若干个字符组成的一个有序的序列。在Java中,使用String这个类来描述字符串。
1) java.lang.String 使用final修饰,不能被继承
2) 字符串底层封装的是字符数组及其针对数组的操作方法
3) 字符串一旦创建,对象永远无法改变,但字符串引用可以重新赋值
4) 字符串在内存中采用Unicode编码方式,任何一个字符对应两个字节的定长编码
5) 字符串的索引值从0开始
1.2字符串常量池
JVM为了提升性能和减少内存开销,避免重复创建字符串,其维护了一块特殊的内存空间,即字符串常量池。当需要使用静态字符串(字面量/常量/常量连接的结果)时,先去检查字符串常量池是否存在该字符串,若存在,则直接返回该字符串的引用地址;若不存在,则在字符串常量池中创建字符串对象,并返回对象的引用地址。
1.3常用构造器
1) String()
初始化一个新创建的空字符序列的字符串对象
2) String(String str)
初始化一个新创建的字符串对象,使其字符序列与参数相同。 换句话说,新创建的对象是该参数的副本
3) String(byte[] bytes)
使用默认编码集解码byte数组,构建一个字符串对象
4) String(byte[] bytes,String charsetName)
使用指定编码集charsetName 解码byte数组,构建一个字符串对象
5) String(byte[] bytes, int offset, int length)
使用默认编码集解码byte数组的从offset开始,length个元素,构建一个字符串对象
6) String(char[] value)
初始化一个字符串对象,使其字符序列包含参数的元素
1.4常用方法
1) length方法
-
length()方法可以获取字符串对象的字符个数。
-
一定要注意,数组的元素个数的获取方式是 引用.length, 不是方法,是属性
String obj = “你好,HelloWorld”; System.out.println(obj.length()); //13
2) 使用indexOf实现检索
-
String类型提供了几个重载的indexOf方法
int indexOf(String str) int indexOf(String str,int fromIndex)
作用:用于返回指定字符串在此字符串中第一次出现的索引,找不到返回-1
-
String还定义了lastIndexOf方法
int lastIndexOf(String str) int lastIndexOf(String str,int endIndex)
作用:用于返回指定字符串在此字符串中最后一次出现的索引,找不到返回-1
3) 使用substring获取子串
-
作用:substring方法用于返回一个字符串的子字符串
-
常用重载方法:
String substring(int beginIndex) String substring(int beginIndex,int endIndex)
4) trim截掉空格
作用:去掉一个字符串的前与后的空字符,不会去掉中间的空字符
String trim()
5) charAt获取字符
作用:返回指定索引处的char值
char charAt(int index)
6) startsWith和endsWith
作用:检查一个字符是否以指定的字符串为前缀或后缀
boolean startsWith(String str) boolean endsWith(String str)
7) 大小写变换
作用:对字符串中的字母进行转换成全部大写或全部小写
String toUpperCase() String toLowerCase()
8) toCharArray
作用: 将字符串转变成字符数组
char[] toCharArray()
9) valueOf
作用:将其他类型转换成字符串类型
static String valueOf(int value) static String valueOf(double d) static String valueOf(char[] ch) static String valueOf(Object obj)
10) equals与==
-
equals方法用于判断两个字符串的内容是否一样
-
==用于判断两个字符串是不是同一个对象
boolean equals(String str)
1.5StringBuilder和StringBuffer
1.5.1 常用构造器
-
StringBuilder()
构造一个不带任何字符的字符串生成器,其初始容量为16个字符
-
StringBuilder(String str)
构造一个字符串生成器,其初始化为指定的字符串内容
1.5.2 常用方法
1) append方法
作用:将指定字符串追加到字符串之后
StringBuilder append(boolean b) StringBuilder append(String str)
2) insert方法
作用:将指定字符串插入到字符串的指定索引处
StringBuilder insert(int index,String str)
查阅API看重载方法
3) delete方法
作用:删除字符串中的一部分
StringBuilder delete(int start , int end)
4) reverse方法
作用:将字符序列进行反转(左右颠倒)
StringBuilder reverse()
5) toString方法
作用:将StringBuilder对象转变成String对象
String toString()
1.5.3两者区别
- StringBuilder是可变字符串,如果进行字符串的内容计算,建议选择StringBuilder,这样性能更好一些。
- java的字符串连接的过程是利用StringBuilder实现的
- StringBuilder 也是final修饰的类型,不能被继承
- StringBuilder没有重写equals方法和toString()
- StringBuilder是非线程安全的,并发处理,性能稍快
- StringBuffer是线程安全的,同步处理,性能稍慢
2.正则表达式
2.2 基本语法
2.2.1 字符集合
[] : 表示匹配括号里的任意一个字符。 [abc] :匹配a 或者 b 或者 c [^abc] : 匹配任意一个字符,只要不是a,或b,或c 就表示匹配成功 [a-z] : 表示匹配所有的小写字母的任意一个。 [A-Za-z] :表示匹配所有的小写字母和大写字母的任意一个。 [a-zA-Z0-9]:表示匹配所有的小写字母和大写字母和数字的任意一个。 [a-z&&[^bc]] :表示匹配所有的小写字母除了b和c, 只要匹配上就是true.
2.2.2 预定义字符集
\d: 用于匹配数字字符中的任意一个 \w: 匹配单词字符中的任意一个 单词字符就是a-zA-Z0-9_ \D: 用于匹配非数字字符中的任意一个 \W: 用于匹配非单词字符中的任意一个 \s: 用于匹配空格,制表符,退格符,换行符等中的任意一个 \S: 用于匹配非空格,制表符,退格符,换行符等中的任意一个 . : 用于匹配任意一个字符
2.2.3 数量词
X? :匹配0个或1个 X* :匹配0个或1个以上 x+ :匹配1个以上 X{n} :匹配n个 X{m,}:匹配m个以上 X{m,n}:匹配m~n个
2.2.4 分组:()
在正则表达式上可以使用()来进行对一些字符分组,并可以使用逻辑运算符|来进行选择匹配 reg: String regex = "(135|137)[\\d]{8}" //匹配手机号是135或者是137开头的
2.2.5 ^和$
^:表示严格从头匹配 $: 表示匹配到结尾
2.3 常用方法
1. boolean matches(String regex) 判断this字符串是否匹配正则表达式regex 2. String[] split(String regex) 对this使用匹配上正则表达式的子串进行切分成字符串数组 3. replaceAll()
2.4Pattern类和Matcher类
2.4.1 Pattern类
1)简介
其实,Pattern这个类,才是真正来操作正则表达式的类,它位于java.util.regex包下。在String类中的提供的 matches 、split 、replace等方 法,其实都是对这个类中的某些方法的封装。
在我们调用String类中的提供的 matches 、split 、replace等方法时,底层就会创建一个Pattern对象。这样的做法效率是很低的。我们何不主动创建一个pattern,然后每次需要匹配就直接用它而不需要再次创建,大大提高了程序的效率。
2)常用方法
-
Pattern.complie(String regex)
Pattern类的构造方法是私有的,不可以直接创建,但可以通过Pattern.complie(String regex)简单工厂方法创建一个正则表达式,
Pattern p=Pattern.compile("\\w+");
-
pattern()
返回正则表达式的字符串形式,其实就是返回Pattern.complile(String regex)的regex参数
2.4.2 Matcher类
Pattern类只能做一些简单的匹配操作,要想得到更强更便捷的正则匹配操作,那就需要将Pattern与Matcher一起合作.Matcher类提供了对正则表达式的分组支持,以及对正则表达式的多次匹配支持。简单来说,Matcher对象就是Pattern对象与字符串匹配的一个结果。
1、获取Matcher类型
Matcher的构造方法是私有的,我们一般通过调用Pattern对象的matcher方法返回一个matcher。
String info = "名字:wulei sda地址:hunan 电话:010-82350555"; Pattern p = Pattern.compile("(名字:\\w+\\s+)|(地址:\\w+\\s+)|(电话:\\d{3}-\\d{8})"); Matcher matcher = p.matcher(info);
2、常用方法
Matcher对象提供了三个不同的匹配方式:matches、 lookingAt()、find()。三个方法均返回boolean类型,当匹配到时返回true,没匹配到则返回false
-
matches:
整个字符串必须符合正则表达式,才会返回true,否则返回false
String info = "123abc"; Pattern p = Pattern.compile("\\d+"); Pattern p1 = Pattern.compile("\\d+\\w+"); Matcher matcher = p.matcher(info); Matcher matcher1 = p1.matcher(info); System.out.println(matcher.matches());//false System.out.println(matcher1.matches());//true
-
lookingAt():
字符串的开头符合使用的正则表达式,返回true。否则返回false。
System.out.println(matcher.lookingAt()); //true、
-
find():
对字符串进行匹配,匹配到的子串可以在任何位置.。每次调用它,matcher里面的匹配指针都会向后移。
//案例1: Pattern p=Pattern.compile("\\d+"); Matcher m=p.matcher("22bb23"); m.find();//返回true Matcher m2=p.matcher("aa2223"); m2.find();//返回true Matcher m3=p.matcher("aa2223bb"); m3.find();//返回true Matcher m4=p.matcher("aabb"); m4.find();//返回false
//案例2: String info = "123abc456def789"; Pattern p = Pattern.compile("\\d+"); Matcher matcher = p.matcher(info); while(matcher.find()){ System.out.println(matcher.group()); } 输出: 123 456 789
-
reset():重置find()的指针。
注意:lookingAt()会影响到find()查找的子字符串
String info = "123abc456def789"; Pattern p = Pattern.compile("\\d+"); Matcher matcher = p.matcher(info); System.out.println("执行lookingAt()后的group:"); matcher.lookingAt(); System.out.println(matcher.group()); //mather.reset(); System.out.println("执行find():"); while(matcher.find()){ System.out.println(matcher.group()); } 输出: 执行lookingAt()后的group: 123 执行find(): 456 789
当我们执行完匹配操作后,我们常常需要获得匹配到的具体字符串。matcher对象能够使用group()、start()、end()方法来获取相关信息。
-
start():返回匹配到的子字符串在字符串中的索引位置.
-
end():返回匹配到的子字符串的最后一个字符在字符串中的索引位置+1
-
group():返回匹配到的子字符串
注意:这三个方法是基于我们matcher执行matches()|lookingAt()|find()并匹配成功的情况下才能使用,否则会报错 此外,这三个方法还有对应的重载方法,start(int index)、end(int index)、group(int index) group(index):返回匹配到的子字符串里的第index个分组,group(0)=group()。 start(index):返回匹配到的子字符串里的第index个分组开始的索引。 end(index):返回匹配到的子字符串里的第index个分组结束的索引+1。
案例演示:
String info = "123abc456def789"; Pattern p = Pattern.compile("(\\d+)([a-z]+)"); Matcher matcher = p.matcher(info); while (matcher.find()){ System.out.println("start(1): " + matcher.start(1)); System.out.println("start(2): " + matcher.start(2)); System.out.println("end(1): " + matcher.end(1)); System.out.println("end(2): " + matcher.end(2)); } 输出: start(1): 0 start(2): 3 end(1): 3 end(2): 6 start(1): 6 start(2): 9 end(1): 9 end(2): 12
现在我们使用一下稍微高级点的正则匹配操作,例如有一段文本,里面有很多数字,而且这些数字是分开的,我们现在要将文本中所有数字都取出来,利用java的正则操作是那么的简单.
Java代码示例:
Pattern p=Pattern.compile("\\d+"); Matcher m=p.matcher("我的QQ是:456456 我的电话是:0532214 我的邮箱是:aaa123@aaa.com"); while(m.find()) { System.out.println(m.group()); } 输出: 456456 0532214 123 如将以上while()循环替换成 while(m.find()) { System.out.println(m.group()); System.out.print("start:"+m.start()); System.out.println(" end:"+m.end()); } 则输出: 456456 start:6 end:12 0532214 start:19 end:26 123 start:36 end:39
注意:只有当匹配操作成功,才可以使用start(),end(),group()三个方法,否则会抛出java.lang.IllegalStateException,也就是当matches(),lookingAt(),find()其中任意一个方法返回true时,才可以使用