1.字符串
1)字符串简介
字符串:是由若干个字符组成的一个有序的序列。在Java中,使用String这个类来描述字符串。
1) java.lang.String 使用final修饰,不能被继承
2) 字符串底层封装的是字符数组及其针对数组的操作方法
3) 字符串一旦创建,对象永远无法改变,但字符串引用可以重新赋值
4) 字符串在内存中采用Unicode编码方式,任何一个字符对应两个字节的定长编码
5) 字符串的索引值从0开始
2)字符串常量池
JVM为了提升性能和减少内存开销,避免重复创建字符串,其维护了一块特殊的内存空间,即字符串常量池
运行机制:当需要使用静态字符串(字面量/常量/常量连接的结果)时,先去检查字符串常量池是否存在该字符串,若存在,则直接返回该字符串的引用地址;若不存在,则在字符串常量池中创建字符串对象,并返回对象的引用地址。
在 JDK 1.7 时,字符串常量池被从方法区转移至 Java 堆中,注意并不是运行时常量池,而是字符串常量池被单独转移到堆,运行时常量池剩下的东西还是方法区中。
什么时候会用到字符串常量池?
当使用字面量给变量赋值时,会先去常量池中寻找是否该字面量的对象,如果有,就将其地址直接给变量。如果没有,就将该字面量对象创建在常量池中,然后将其地址赋值给变量。
1.直接用字面量给变量赋值时,地址是相同的。
String s1 = "abc"; //
String s2 = "abc"; //
//判断s1和s2的对象地址是不是同一个
System.out.println(s1 == s2); //true
2.两个字面量做拼接操作时,编译器在编译期间就做了优化操作
/*
* 两个字面量做拼接操作时,编译器在编译期间就做了优化操作
* 直接计算出结果,即s3="abcd"
*/
String s3 = "abc"+"d";
String s4 = "abcd";
System.out.println(s3 == s4); //true
3.拼接操作只要有变量参与,那么javac不会进行优化。只能在运行期间进行计算,在堆中开辟空间,所以计算后的结果,存储在堆中,并不是常量池里
String s5 = "d";
// 拼接操作只要有变量参与,那么javac不会进行优化。只能在运行期间进行计算,
// 计算后的结果,存储在堆中,并不是常量池里
String s6 = "abc"+s5;
System.out.println(s6 == s4); //false
字面量进行拼接javac编译器会进行优化
String s7 = "ab"+"c"+s5; // 优化成了"abc"+s5. 但是依然在运行期间与s5做的计算. 不会去堆里找,是新对象
System.out.println(s7 == s6); // false
4.new一个字符串对象
String s8 = new String("d"); //对象存储在堆中
String s9 = "abc"+s8; //在堆中做运算
System.out.println(s7 == s9);//false
5.创建两个对象
String s10 = new String("abc");
String s11 = new String("abc");
System.out.println(s10 == s11);//false //创建了两个对象
6.假如只有下面两行代码:问 内存中总共有多少个对象 5个对象
String s12 = "h"; // "h" "abc" "o"在字符串常量池里 "abcho" 创建一个对象s13 在堆里
String s14 = "abc"+s12+"o";
String s13 = new String(s14);
构建字符串对象:
1. 可以直接赋值字面量
String name = "michael"; // 直接赋值字面量。
2. 也可以调用构造器
3)常用构造器
1) String() 无参构造器
初始化一个新创建的空字符序列的字符串对象
//无参构造器, 构建的是一个"" 实际上底层是 char[] value = new char[0];
String str = new String();
System.out.println(str.length()); //0
2) String(String str)
初始化一个新创建的字符串对象,使其字符序列与参数相同。 换句话说,新创建的对象是该参数的副本
//构造器: String(String str)
String s1 = new String("michael");
System.out.println("s1 = " + s1);
3) String(byte[] bytes)
使用默认编码集解码byte数组,构建一个字符串对象
//构造器:String(byte[] bytes) : 传入一个字节序列,按照默认字符集转成对应字符。
byte[] bytes = {-28, -72, -83, -27, -101, -67};//中国两个字的字节序列
String s2 = new String(bytes);
System.out.println("s2 = " + s2); //中国
4) String(byte[] bytes,String charsetName)
使用指定编码集charsetName 解码byte数组,构建一个字符串对象
//构造器:String(byte[] bytes,String charsetName);
String s3 = new String(bytes,"UTF-8");
System.out.println("s3 = " + s3);//中国
5) String(byte[] bytes, int offset, int length)
使用默认编码集解码byte数组的从offset开始,length个元素,构建一个字符串对象
//String(byte[] bytes, int offset(开始位置), int length(长度))
String s4 = new String(bytes,3,3);
System.out.println("s4 = " + s4);//国
6) String(char[] value)
初始化一个字符串对象,使其字符序列包含参数的元素(即可以把字符数组转换成字符串)
//String(char[] value)
String s5 = new String(new char[]{'h','e','l','l','o'});
System.out.println(s5);
4)常用方法
1.length方法:可以获取字符串对象的字符个数。
//length方法
String s1 = "welcome to china";
System.out.println(s1.length());//16
2.使用indexOf实现检索
String类型提供了几个重载的indexOf方法
int indexOf(String str) 用于返回指定字符串在此字符串中第一次出现的索引,找不到返回-1
int indexOf(String str,int fromIndex) 返回指定字符串在此字符串的fromIndex索引之后的字符串中的第一次出现的索引,(即可以理解为 从fromIndex索引处开始找)
/**
* 用于检测子字符串所在的位置,如果没有找到,返回-1.
* 用于返回指定字符串在此字符串中第一次出现的索引,找不到返回-1
* int indexOf(String str)
* int indexOf(String str,int fromIndex)
*/
int index = s1.indexOf("come");
System.out.println("index is " + index);//3 子字符串开始的第一个字符位置
//找到第二个o的下标
//index = s1.indexOf("o",5); // 从fromIndex索引处开始找指定字符串在此字符串中第一次出现的索引
index = s1.indexOf("o",s1.indexOf("o")+1);//找到第一个"o"的索引,然后加1,往后继续找,就能找到第二个"o".
System.out.println("index is " + index);
String还定义了lastIndexOf方法
int lastIndexOf(String str) 用于返回指定字符串在此字符串中最后一次出现的索引,找不到返回-1
int lastIndexOf(String str,int endIndex) 检索子串最后一次出现的位置。从左到右一直检索到指定索引endIndex. (可以理解为,从前往后只检索到endIndex)
/**
* 检索子字符串最后一次出现的索引。
* int lastIndexOf(String str)
* int lastIndexOf(String str,int endIndex):
* 检索子串最后一次出现的位置。从左到右一直检索到指定索引endIndex.
*/
index = s1.lastIndexOf("o");
System.out.println("index is " + index);//9
index = s1.lastIndexOf("o",8); //
System.out.println("index is " + index);//4
3.使用substring获取子串
常用重载方法:
String substring(int beginIndex)用于返回一个字符串的子字符串 (beginIndex开始的之后的子字符串)
String substring(int beginIndex,int endIndex) beginIndex开始位置 endIndex结束位置(不包括该位置的字符)(即包前不包后)
String substring = s1.substring(11);
System.out.println("子串:" + substring);//china
String substring1 = s1.substring(8,12);//to c
System.out.println("子串:" + substring1);
4.trim截掉空格:去掉一个字符串的前与后的空字符,不会去掉中间的空字符
String trim()
String s2 = " mic hael ";
System.out.println("长度:"+s2.length());//9
s2 = s2.trim();
System.out.println("长度:"+s2.length());//7
System.out.println(s2); //mic hael
5.charAt获取字符:返回指定索引处的char值
char charAt(int index)
/**
* char charAt(): 获取指定下标上的字符, 可用于单个字符的字符串转成字符类型
*/
char c = s1.charAt(1);
System.out.println("c:"+c);//e
6.startsWith和endsWith:检查一个字符串是否以指定的字符串为前缀或后缀
/**
* boolean startsWith(String str): 判断字符串是否以指定子串开头。
* boolean endsWith(String str): 判断字符串是否以指定子串结尾。
*/
boolean we = s1.startsWith("we");
boolean na = s1.endsWith("na");
System.out.println(we+","+na);//true,true
7.大小写转换
String toUpperCase()对字符串中的字母进行转换成全部大写
String toLowerCase()对字符串中的字母进行转换成全部小写
String s3 = "你好welComE+";
System.out.println(s3.toUpperCase());//你好WELCOME+
System.out.println(s3.toLowerCase());//你好welcome+
1.Character类中的判读字母的大小写:
boolean Character.isUpperCase(char ch) //判断是不是大写字母
boolean Character.isLowerCase(char ch) //判断是不是小写字母
2.字母大小写互转
char cha = Character.toLowerCase(char ch) //转成小写字母
char cha1 = Character.toUpperCase(char ch) //转成大写字母
案例: 将一个字符串中的大小写字母翻转
例如:
reverse("heLLo woRld") -> HEllO WOrLD
public static String getReverse(String str){
//把字符串转成字符数组
char[] array = str.toCharArray();
//遍历字符数组中的每一个字符
for (int i = 0; i < array.length; i++) {
//判段一个字符是不是大写字母
if (Character.isUpperCase(array[i])){
array[i] = Character.toLowerCase(array[i]);
}else if (Character.isLowerCase(array[i])){
array[i] = Character.toUpperCase(array[i]);
}
}
return new String(array);//转成字符串输出
}
8.toCharArray:将字符串转变成字符数组
char[] toCharArray()
char[] charArray = s1.toCharArray();
System.out.println(Arrays.toString(charArray));//[w, e, l, c, o, m, e, , t, o, , c, h, i, n, a]
9.valueOf:将其他类型转换成字符串类型
static String valueOf(int value)
static String valueOf(double d)
static String valueOf(char[] ch)
static String valueOf(Object obj)
String num = String.valueOf(10001);
System.out.println("num:"+num);
10.equals与==
equals方法用于判断两个字符串的内容是否一样
boolean equals(String str)
==用于判断两个字符串是不是同一个对象 ,即地址是否相等
String s10 = new String("hello");
String s11 = new String("hello");
System.out.println(s10 == s11); //false
System.out.println(s10.equals(s11));//true
11. concat() 方法:用于连接两个字符串。
该方法属于 String 类,使用它可以将一个字符串连接到另一个字符串的末尾。
需要注意的是,concat() 方法不会修改原字符串,而是返回一个新的字符串。
语法:String concat(String s) //s是要连接的字符串(即s字符串连接在末尾)
案例:
public class Test {
public static void main(String args[]) {
String s = "菜鸟教程:";
s = s.concat("www.runoob.com");
System.out.println(s);
}
}
结果: 菜鸟教程:www.runoob.com
5)StringBuilder和StringBuffer
因为直接操作String类型,会造成大量的对象在内存中出现.所以影响性能,所以可以使用StringBuilder或StringBuffer来操作字符串的拼接,替换,截断等操作。 因为:StringBuilder和StringBuffer是一个可变字符串类型。拼接,替换,截断都不会产生的新的对象。
StringBuilder和StringBuffer类中的方法完全相同
1.常用构造器
(1)StringBuilder() :构造一个不带任何字符的字符串生成器,其初始容量为16个字符
StringBuilder s1 = new StringBuilder();
(2)StringBuilder(String str) :构造一个字符串生成器,其初始化为指定的字符串内容
StringBuilder s2 = new StringBuilder("");
2.常用方法
(1)append方法 :将指定字符串追加到字符串之后
StringBuilder append(boolean b)
StringBuilder append(String str) 还有int、char[]、double、float、long类型的都可追加到字符串后面。
StringBuilder s3 = s1.append("欢迎"); //return this
System.out.println(s1==s3);//true, 表示s1和s3指向的是同一个对象
s1.append("来到中国").append(",中国是美丽的").append(",地大物博的");
System.out.println(s1.toString());
(2)insert方法 :将指定字符串插入到字符串的指定索引处
StringBuilder insert(int index,String str) 从index处开始插入
s1.insert(4,"伟大的");
System.out.println("s1:"+s1);
(3)delete方法 :删除字符串中的一部分
StringBuilder delete(int start , int end) 从start开始,到end索引的前一个字符都删除。
s1.delete(13,17); //包前不包后 //删除“美丽的,”
System.out.println(s1);
(4)reverse方法:将字符序列进行反转(左右颠倒)
StringBuilder reverse()
s1.reverse();
System.out.println(s1);
(5)toString方法:将StringBuilder对象转变成String对象
String toString()
3.三者的区别
-
StringBuilder是可变字符串,如果进行字符串的内容计算,建议选择StringBuilder,这样性能更好一些。
-
java的字符串连接的过程是利用StringBuilder实现的
-
StringBuilder 也是final修饰的类型,不能被继承
-
StringBuilder没有重写equals方法和toString()
-
StringBuilder是非线程安全的,并发处理,性能稍快
-
StringBuffer是线程安全的,同步处理,性能稍慢
2.正则表达式
1)简介
正则表达式(Regular Expressions),是一个特殊的字符串,可以对普通的字符串进行校验检测等工作。正则表达式不是Java特有的,它是一套独立的语法,可以在java,c++,python等语言中使用。
正则表达式,最基本的使用场景是用来做校验,校验一个字符串是否满足预设的规则。在校验的基础 上,又添加了若干个其他的引用场景,例如: 批量的查找、替换、切割...
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.预定义字符集
\d 相当于[0-9]: 用于匹配数字字符中的任意一个
\w [a-zA-Z0-9_]: 匹配单词字符中的任意一个 单词字符就是[a-zA-Z0-9_]
\D: 用于匹配非数字字符中的任意一个
\W: 用于匹配非单词字符中的任意一个
\s: 用于匹配空格,制表符,退格符,换行符等中的任意一个
\S: 用于匹配非空格,制表符,退格符,换行符等中的任意一个
. : 用于匹配任意一个字符
3.数量词
X? :匹配0个或1个
X* :匹配0个或1个以上
x+ :匹配1个或1个以上
X{n} :匹配n个
X{m,}:匹配m个以上
X{m,n}:匹配m~n个
4.分组 ()
在正则表达式上可以使用()来进行对一些字符分组,并可以使用逻辑运算符|来进行选择匹配
reg:
String regex = "(135|137)[\\d]{8}" //匹配手机号是135或者是137开头的
5.^和$
^:表示严格从头匹配
$: 表示匹配到结尾
3)常用方法
1. boolean matches(String regex)
判断this字符串是否匹配正则表达式regex
字符集合案例演示:
//给定的字符串是否满足正则表达式
System.out.println("a".matches("[abcdefg]")); //true
String regex = "[^hg]";
String str = "o";
System.out.println(str.matches(regex)); //true
System.out.println("abc".matches("[a-z]"));//false
System.out.println("b".matches("[A-Za-z]"));//true
System.out.println("ab".matches("[a-zA-Z0-9]"));//false
System.out.println("b".matches("[a-z&&[^bc]]"));//false
预定义字符集演示:
System.out.println("+".matches(".")); //true//匹配一下+是不是一个字符串。
System.out.println(".".matches("."));//true
System.out.println("-".matches("\\.")); // false \\ . 通配符点变成了普通的点符号
System.out.println("c".matches("[\\w]"));//true添加中括号
System.out.println("c".matches("\\w")); //true不添加中括号也可以
System.out.println("45".matches("\\d"));//flase
System.out.println(" ".matches("\\s"));//true
有数量词的演示:
System.out.println("12".matches("[0-9]?"));//false
System.out.println("123".matches("\\d*"));//true
System.out.println("a".matches("\\w+"));//true
//匹配密码:密码必须是8的数字或者字母组合
System.out.println("123abc45".matches("[a-zA-Z0-9]{8}")); //true
System.out.println("123abc4".matches("[a-zA-Z0-9]{8}")); //false
System.out.println("123abc456".matches("[a-zA-Z0-9]{8}")); //false
//匹配用户名: 用户名是由字母数字和下划线组成,5~8位
System.out.println("_abc123".matches("\\w{5,8}")); //true
System.out.println("_abc123+".matches("\\w{5,8}")); //false
分组:
String regex1 = "(13|18|15)(7|8|9)[\\d]{8}";
System.out.println("13811110000".matches(regex1));//true
System.out.println("13311110000".matches(regex1));//false
还来可以进行检验普通字符串是否符合一个正则表达式。
案例:检测用户名是否匹配成功
public static void main(String[] args) {
String username = "michael123";
String regex = "[a-zA-Z][\\w]{7,9}";
//检查用户名是否匹配正则表达式
boolean flag = username.matches(regex);
if (flag) {
System.out.println("用户名可用");
}else{
System.out.println("用户名不可用,必须首字符是字母,总长度是8到10位");
}
} //用户名可用
2. String[] split(String regex)
用匹配上正则表达式的该普通字符串的子串把该普通字符串进行切分,切分成字符串数组
String str = "hello111world222welcome333";
//请使用数字将其切分成字符串数组。
String regex1 = "\\d+";
String[] arr = str.split(regex1);
System.out.println(Arrays.toString(arr));
System.out.println("数组的长度:"+arr.length);
就以上面的正则表达式来说:如果是数字开头,则被切割成数组时,必须要有逗号。
开头是一个空字符。
public static void main(String[] args) {
String str = " ";
String[] arr;
String regex1 = "\\d+";
str = "888aaa9bbb10ccc";
arr = str.split(regex1);
System.out.println(Arrays.toString(arr));
System.out.println("数组的长度:"+arr.length);
}
3. replaceAll()
String replaceAll(String regex,String replacement)
作用:使用replacement这个串替换掉所有的符合正则表达式的子串
案例1:
public static void main(String[] args) {
String info = "no zuo no die";
info = info.replaceAll("no","yes");
System.out.println("info:"+info);
}
案例2:
public static void main(String[] args) {
String info = "";
info = "https://www.baidu123.com.cn.com456";
//将所有的字母替换成#
String regex = "[a-zA-Z]+"; //带上+表示匹配1个以上
info = info.replaceAll(regex,"#");
System.out.println("info:"+info);
}
3.Pattern类和Matcher类
1)Pattern类
1.简介
其实,Pattern这个类,才是真正来操作正则表达式的类,它位于java.util.regex包下。在String类中的提供的 matches 、split 、replace等方 法,其实都是对这个类中的某些方法的封装。
在我们调用String类中的提供的 matches 、split 、replace等方法时,底层就会创建一个Pattern对象。这样的做法效率是很低的。我们何不主动创建一个pattern,然后每次需要匹配就直接用它而不需要再次创建,大大提高了程序的效率。
2.常用方法
(1)Pattern.complie(String regex)
Pattern类的构造方法是私有的,不可以直接创建,但可以通过Pattern.complie(String regex)简单工厂方法创建一个正则表达式,。
String regex = "[a-zA-Z][_$a-zA-Z0-9]{7,9}";//以字母开头_结尾
//获取一个Pattern对象
Pattern p1 = Pattern.compile(regex);
和普通字符串进行校验, 会得到一个Matcher类的对象,该对象里封装的是匹配的结果,并且提供了各种操作
Matcher matcher = p1.matcher("michael12_");
// 想要得到是否匹配成功,需要调用Matcher里的matches()。 该方法的作用是从头到尾进行严格匹配
// 匹配成功,返回true, 失败返回false;
boolean matches = matcher.matches();
System.out.println("是否匹配成功:" + matches);//true
(2)pattern()
返回正则表达式的字符串形式,其实就是返回Pattern.complile(String regex)的regex参数
Pattern p=Pattern.compile("\\w+");
p.pattern();//返回 \w+
(3)matcher(String str); 返回一个Matcher对象
(4)String[] split(String str) 作用: 对字符串进行切分。使用符合正则表达式的子串进行切分,返回字符串数组。 * 符合正则表达式的子串,就相当于隔板,不要了。
public static void main(String[] args) {
String regex = "\\d+";
String str = "aaa111bbb222ccc";
//获取一个Pattern对象
Pattern p1 = Pattern.compile(regex);
String[] arr = p1.split(str);
System.out.println(Arrays.toString(arr));//[aaa, bbb, ccc]
}
2)Matcher类
1.获取Matcher类型
Matcher的构造方法是私有的,我们一般通过调用Pattern对象的matcher方法返回一个matcher。
Pattern p = Pattern.compile("\\d+");
Matcher matcher = p.matcher("123");
2.常用方法
(1)matches:整个字符串必须符合正则表达式,才会返回true,否则返回false
public static void main(String[] args) {
Pattern p = Pattern.compile("\\d+");
Matcher matcher = p.matcher("123");
boolean matchs = matcher.matches();
System.out.println(matchs);//true
}
(2)lookingAt():字符串的开头符合使用的正则表达式,返回true。否则返回false。
内部含有一个类似于指针的操作,当匹配成功后,指针指向了匹配成功的子串
匹配前指针位于普通字符串的前面。
public static void main(String[] args) {
String regex = "\\d+";
String info = "abc123";
Pattern pattern = Pattern.compile(regex); //获取模式对象
Matcher matcher = pattern.matcher(info); //获取匹配结果对象
//调用了lookingAt()方法
boolean result = matcher.lookingAt();
System.out.println("result:" + result);//false
}
(3)find():用于匹配普通字符串里是否有符合正则表达式的子串,检索到字符串的最后。如果有,返回true.
该方法也有一个指针操作,当匹配成功后,指针就向后移动。
注意: 匹配前,指针还是在字符串之前
public static void main(String[] args) {
String regex = "\\d+";
String info = "abc123eee444ff555ggg";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(info);
//循环的次数,表示了find()找到的符合正则表达式要求的个数。
while (matcher.find()) {
System.out.println("--匹配成功-");//匹配成功
}
}
(4)reset():重置find()的指针。
public static void main(String[] args) {
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());
//因为再使用lookingAt()方法,指针向后移动了一次
// 所以再使用find()方法时,指针就不是从字符串前开始移动的,而是紧随着lookingAt()方法的位置移动。
// 注意:指针重置
//mather.reset(); // 如果不重置指针,会影响下面find()的执行结果
System.out.println("执行find():");
while(matcher.find()){
System.out.println(matcher.group());
}
}
(5)String group(): 作用: 用于返回指针指向的符合正则表达式的那一部分。
public static void main(String[] args) {
/*
* String group():
* 作用: 用于返回指针指向的符合正则表达式的那一部分。
*/
Pattern pattern = Pattern.compile("\\d+");
Matcher matcher = pattern.matcher("abc123def456xxx");
while (matcher.find()) {
System.out.println(matcher.group());//123 456
}
// 当使用find()后,指针已经移动到了符合正则表达式的最后一个部分。因此再次调用find(),会继续向后
// 检索,直到检索到没有任何符合正则表达式的group()
// 如果想要从头检索,需要重置指针
matcher.reset();
while (matcher.find()) {
System.out.println(matcher.group());//123 456
}
}
(6)start() ,end()
int start(): 用于返回符合正则表达式的子串的开始位置(第一个字符的位置)
int end(): 用于返回符合正则表达式的子串的最后一个字符的位置+1
public static void main(String[] args) {
Pattern pattern = Pattern.compile("\\d+");
Matcher matcher = pattern.matcher("abc123def456xxx");
int count = 1;
while (matcher.find()) {
int start = matcher.start();
int end = matcher.end();
System.out.println("第"+count+"部分的开始和结束位置:"+start+","+end);
count++;
}
}
(7)groupCount():作用:用于获取正则表达式中的小括号的个数。() 用于分组。
public static void main(String[] args) {
Pattern pattern = Pattern.compile("((ca)(t))s");
Matcher matcher = pattern.matcher("one cat, two cats in the yard");
System.out.println(matcher.groupCount());
while (matcher.find()) {
// 打印符合正则表达式的子串, 因此循环次数是3次。
System.out.println(matcher.group());
}
/**
* 使用小括号的个数来循环, 可以使用group的重载方法:
* String group(int group)
*
* 注意:想要使用()的个数进行遍历,需要将指针移动到字符串之前,然后还需要调用一下find方法
*
* group(0): 表示的是对组进行拆分括号的整体的样子
* group(1): 表示第一个括号
* group(2): 表示第二个括号
* group(3): 表示第三个括号
*/
matcher.reset();
matcher.find();
for (int i = 0; i <=matcher.groupCount(); i++) {
System.out.println(matcher.group(i));
}
}
注意:只有当匹配操作成功,才可以使用start(),end(),group()三个方法,否则会抛出java.lang.IllegalStateException,也就是当matches(),lookingAt(),find()其中任意一个方法返回true时,才可以使用