public class Test {
public static void main(String[] args) throws IOException {
Pattern p = Pattern.compile("\\d+");//Pattern类用于创建一个正则表达式(匹配模式)。匹配一个或多个数字字符。等价于 [0-9]+
Matcher m = p.matcher("22bb23");//返回正则表达式的字符串形式(将给定的正则表达式编译到模式中)
//分隔字符串,并返回一个String[]
String[] splitStrs = p.split("我的QQ是:456456我的电话是:0532214我的邮箱是:aaa@aaa.com");
System.out.println(Arrays.toString(splitStrs));//[我的QQ是:, 我的电话是:, 我的邮箱是:aaa@aaa.com]
//快速匹配字符串,该方法适合用于只匹配一次且匹配全部字符串
System.out.println(Pattern.matches("\\d+", "1243"));//true
System.out.println(Pattern.compile("\\d+").matcher("1243").matches());//true
System.out.println(Pattern.matches("\\d+", "1243aa"));//false。需要匹配到所有字符串才能返回true,这里aa不能匹配到
System.out.println(Pattern.matches("\\d+", "12bb43") + "\n");//false
//Pattern类只能做一些简单的匹配操作,Matcher类提供了对正则表达式的分组支持,以及对正则表达式的多次匹配支持
System.out.println(p == m.pattern());//true,返回创建该Matcher对象的哪个Pattern对象
//matches():对整个字符串进行匹配,只有整个字符串都匹配了才返回true
System.out.println("是否匹配:" + p.matcher("22bb23").matches());//false。因为bb不能被\d+匹配,导致整个字符串匹配未成功.
System.out.println("是否匹配:" + p.matcher("2223").matches());//true
//lookingAt():对前面的字符串进行匹配,只要最前面的字符串能匹配到就返回true
System.out.println(p.matcher("2bbb23").lookingAt());//true,因为\d+匹配到了最前面的2
System.out.println(p.matcher("a12223").lookingAt() + "\n");//false,因为\d+不能匹配最前面的a
//find():对字符串进行匹配,匹配到的字符串可以在任何位置
System.out.println("是否找到:" + p.matcher("aa2").find());//true
System.out.println("是否找到:" + p.matcher("aa2223bb").find());//true
System.out.println("是否找到:" + p.matcher("aabb").find() + "\n");//false
//当使用matches()、lookingAt()、find()执行匹配操作后,就可以利用以下三个方法得到更详细的信息
m = p.matcher("我的QQ是:456456 我的电话是:0532214 我的邮箱是:aaa123@aaa.com");
while (m.find()) {//注意:matcher只有在执行这几个方法后且返回true时才能执行以下方法,否则报 IllegalStateException: No match available
//返回匹配到的子字符串,及其第一个/最后一个字符,在字符串中的索引位置,范围仍然为【[ , )】
System.out.println("查找 " + m.group() + ": " + m.start() + "-" + m.end());////【456456: 6-12】【0532214: 19-26】【123: 36-39】
}
m = p.matcher("21bb");
if (m.lookingAt()) {//这里若用用while会导致死循环
System.out.println("lookingAt " + m.group() + ": " + m.start() + "-" + m.end() + "\n");//lookingAt 21: 0-2
}
//【这里不是很明白】start()、end()、group()均有一个带int参数的重载方法,专用于分组操作;groupCount()用于返回有多少组
//捕获组可以通过从左到右计算其开括号来编号,编号是从1 开始的。例如,在 ((A)(B(C)))中,存在四个这样的组【1 ((A)(B(C)));2 (A);3 (B(C));4 (C)】
//组零始终代表整个表达式。 以 (?) 开头的组是纯的非捕获组,它不捕获文本,也不针对组合计进行计数。
p = Pattern.compile("([a-z]+)(\\d+)");
m = p.matcher("aa22bb33cc44");
if (m.find()) {
int count = m.groupCount();
for (int i = 1; i <= count; i++) {//注意是从1开始的
System.out.println("分组" + i + " " + m.group(i) + ":" + m.start(i) + "-" + m.end(i));//【分组1 aa:0-2】【分组2 22:2-4】
}
}
//可以先后使用 appendReplacement 和 appendTail 方法将结果收集到现有的字符串缓冲区
p = Pattern.compile("cat");
m = p.matcher("one cat two cats in the yard");
StringBuffer buffer = new StringBuffer();
while (m.find()) {
m.appendReplacement(buffer, "dog");//实现非终端添加和替换步骤,返回匹配器
}
m.appendTail(buffer);//实现终端添加和替换步骤,返回目标字符串缓冲区(即参数本身)
System.out.println("appendTail: " + buffer.toString());//one dog two dogs in the yard
//replaceFirst :替换模式与给定替换字符串匹配的输入序列的第一个子序列
String result = "";
m = p.matcher("one cat two cats in the yard");
if (m.find()) {//只能使用if
result = m.replaceFirst("包青天");//调用此方法将更改此匹配器的状态。如果在将来的匹配操作中使用该匹配器,则应该首先重置它
}
System.out.println("replaceFirst: " + result);//one 包青天 two cats in the yard
m = p.matcher("one cat two cats in the yard");
while (m.find()) {
result = m.replaceFirst("包青天");//调用此方法将更改此匹配器的状态。如果在将来的匹配操作中使用该匹配器,则应该首先重置它
m = p.matcher(result);
}
System.out.println("replaceFirst+while: " + result);//one 包青天 two 包青天s in the yard
m = p.matcher("one cat two cats in the yard");
while (m.find()) {
result = m.replaceAll("白乾涛");//调用此方法将更改此匹配器的状态。如果在将来的匹配操作中使用该匹配器,则应该首先重置它
}
System.out.println("replaceAll: " + result);//one 白乾涛 two 白乾涛s in the yard
}
}