目录
一.正则表达式:单个字符
1.如何表示单个字符?
2.如何表示除了这个字符以外的单个字符?
3.如何表示某一段范围内的字符?
4.如何表示多段范围内的字符?
5.如何表示两段字符的交集?
6.如何去除某段字符中的某几个字符?
7.如何去除某段字符中的某段字符?
8.某段字符中去除多段字符?
public class Demo191 {
public static void main(String[] args) {
System.out.print("1.abc当中的任意一个字符:(一个方括号代表一个字符)");
System.out.println("a".matches("[abc]"));
System.out.print("2.非abc的任意一个字符:");
System.out.println("?".matches("[^abc]"));
System.out.println("可以注意到-左右两边连接两个字符,这三个字符:”*-*“这就代表了这个范围内的某个字符");
System.out.print("3.全字母:");
System.out.println("R".matches("[a-zA-z]"));
System.out.print("4.多段范围的字母:");
System.out.println("f".matches("[[a-b][c-d][e-f]]"));
System.out.print("5.某段范围与某几个字母的交集");
System.out.println("e".matches("[a-z&&d-f]"));
System.out.println("上面的中括号里面的中括号可加可不加,但是到了下面碰到了^这个字符,就需要加中括号");
System.out.print("6.某段范围中去除某几个字母:");
System.out.println("r".matches("[a-z&&[^aple]]"));
System.out.print("7.某段范围中去除某一段字母:");
System.out.print("r".matches("[a-z&&[^d-f]]") + " ");//等价写法
System.out.println("r".matches("[a-cg-z]"));
System.out.print("8.某段范围中去除多段字母:");
System.out.print("z".matches("[a-z&&[^d-f]&&[^j-y]]") + " ");
System.out.println("z".matches("[a-cg-iz]"));//等价写法
}
}
二.正则表达式:匹配预定义的单个字符
1.使用预定义字符用正斜杠还是反斜杠?大字母与小字母的区别?
2.如何匹配任何字符?
3.如何匹配数字?
4.如何匹配空白?
5.如何匹配数字字母下划线?
public class Demo192 {
public static void main(String[] args) {
System.out.println("1.使用反斜杠:小写字母匹配是,大写字母匹配否");
System.out.print("2.匹配任何单个字符。需要注意.不能够匹配换行符号\\n:");
System.out.println("原".matches("."));
System.out.print("3.匹配数字:");
System.out.println("6".matches("\\d"));
System.out.print("匹配非数字:");
System.out.println("6".matches("\\D"));
System.out.print("4.匹配空白字符:");
System.out.println(" ".matches("\\s"));
System.out.print("匹配非空白字符:");
System.out.println(" ".matches("\\S"));
System.out.print("5.匹配数字字母下划线:");
System.out.println("_".matches("\\w"));
System.out.print("匹配非数字字母下划线;");
System.out.println("_".matches("\\W"));
}
}
三.正则表达式:数量控制
1.如何使字符出现的的次数为0或1?
2.如何使字符出现次数为0到无穷?
3.如何使字符出现次数至少为1次?
4.如何使字符只出现n次?
5.如何使字符出现至少n次?
6.如何使字符出现至少m次,至多n次?
public class Demo193 {
public static void main(String[] args) {
System.out.println("1.出现次数:0-1,“?”代表有没有这个数呢?有或者是没有,可以理解成0或者1");
System.out.println("".matches("\\w?"));
System.out.println("R".matches("\\w?"));
System.out.println("RR".matches("\\w?"));
System.out.println("2.出现次数:0-无穷,”*“代表我不知道这里有多少个,或者是有多少,反正不可能是负数吧");
System.out.println("".matches("\\w*"));
System.out.println("RRRRRRR".matches("\\w*"));
System.out.println("3.出现次数:1-无穷,“+”代表至少有一个");
System.out.println("".matches("\\w+"));
System.out.println("R".matches("\\w+"));
System.out.println("RRRRRR".matches("\\w+"));
System.out.println("4.出现次数:n次,“{}”代表范围,没有两个数则代表刚好有n个数,有逗号隔开则代表有范围");
System.out.println("RRR".matches("\\w{5}"));
System.out.println("RRRRR".matches("\\w{5}"));
System.out.println("5.出现次数:至少m次");
System.out.println("RRR".matches("\\w{5,}"));
System.out.println("RRRRR".matches("\\w{5,}"));
System.out.println("RRRRRRR".matches("\\w{5,}"));
System.out.println("6.出现次数:至少m至多n");
System.out.println("RRR".matches("\\w{5,10}"));
System.out.println("RRRRRRR".matches("\\w{5,10}"));
System.out.println("RRRRRRRRRRR".matches("\\w{5,10}"));
}
}
四.正则表达式实战:匹配邮箱
1.在表示单个字符的时候如果省去外围的[] ,则&&符号会不会生效?
2.如何多次表示某一段字符?
3.如何表示小数点这个符号?
4.怎么用正则搜索if else的结构:比如说搜索com或者是cn:
[com]?[cn]?这样写会搜索到com后面也接着一个cn的情况,如何只搜索com或者只搜索cn呢?
public class Demo194 {
public static void main(String[] args) {
String email = "3342824499@qq.com.cn";
String myEmail = "SunCoya@163.com";
System.out.println("1.这里在表示数字字母时,去掉了下划线的情况,在表示单个字符时需要加外围的“[ ]”");
System.out.println("外围没有[],则&&不会生效,只是表示这两个字符");
System.out.println("2.小括号代表分组,后面可以接上数量控制,可以表示多段匹配内容的字符");
System.out.println("3.这里小数点要转义w(゚Д゚)w:\\.在正则里面表示小数点,非任意字符");
System.out.println(email.matches("[\\w&&[^_]]+@[\\w&&[^_]]+(\\.[a-zA-Z]{2,3}){1,2}"));
System.out.println(myEmail.matches("[\\w&&[^_]]+@[\\w&&[^_]]+(\\.[a-zA-Z]{2,3}){1,2}"));
System.out.println("4.使用|表示或,后面记得加大括号限定范围,不加大括号限定范围会导致只匹配cn");
System.out.println(myEmail.matches("\\w*@\\w*\\.(com|cn|edu)"));
System.out.println(myEmail.matches("\\w*@\\w*\\.com|cn"));
}
}
五.忽略大小写匹配
1.匹配正则表达式如何忽略大小写?
2.如何显示忽略大小写的范围?
public class Demo195 {
public static void main(String[] args) {
System.out.println("1.忽略大小写的正则表达式:(?i)后面的内容就是忽略大小的内容");
String regex = "(?i)abc";
System.out.println("ABC".matches(regex));
System.out.println("2.使用括号限定范围");
regex = "((?i)a)bc";
System.out.println("Abc".matches(regex));
}
}
六.本地爬虫
本地爬虫需要用到的两个类:
1.Pattern是什么类?
2.Matcher是什么类?
本地爬虫步骤:
1.如何获取Pattern对象?
2.如何获取matcher对象?
3.如何使用matcher判断是否有匹配的字符?
4.如何提取出matcher匹配到的对象?
5.如何使用循环来进行爬虫?
public class Demo196 {
public static void main(String[] args) {
String str = "Java自从95年问世以来,经历了很多版本,目前企业中用的最多的是Java8和Java11," +
"因为这两个是长期支持版本,下一个长期支持版本是Java17,相信在未来不久Java17也会逐渐登上历史舞台";
System.out.println("本地爬虫需要使用的类");
System.out.println("1.Pattern类:表示正则表达式");
System.out.println("2.Matcher类:文本匹配器,按正则表达式规则从头读取字符串:在大串中找符合匹配规则的字串");
System.out.println("1.使用静态方法compile获取Pattern对象:正则表达式的对象");
Pattern p = Pattern.compile("Java\\d{0,2}");
System.out.println("2.使用Pattern的matcher方法获取文本匹配器的对象:要在str字符串中找符合p规则的小串串");
Matcher m = p.matcher(str);
System.out.println("3.根据find方法寻找是否有满足规则的字串,没有则返回false,有则返回true,在底层记录字串位置");
System.out.println(m.find());
System.out.println("4.根据find方法记录的索引,使用group方法进行字符串截取,到这里也只是截取了一个");
String str1 = m.group();
System.out.println(str1);
System.out.println("第二次调用的时候会继续往后面读,重新进行记录");
System.out.println(m.find());
str1 = m.group();
System.out.println(str1);
System.out.println("5.使用循环案例:");
Matcher m2 = p.matcher(str);
while (m2.find()) {
String strFind = m2.group();
System.out.print(strFind + " ");
}
}
}
七.爬取网络上面的文档
爬虫时如何忽略掉匹配字符串后面与前面的内容?
public class Demo197 {
public static void main(String[] args) throws IOException {
//创建URL对象
URL url = new URL("https://wiki.52poke.com/wiki/%E5%AE%9D%E5%8F%AF%E6%A2%A6%E5%88%97%E8%A1%A8%EF%BC%88%E6%8C%89%E5%85%A8%E5%9B%BD%E5%9B%BE%E9%89%B4%E7%BC%96%E5%8F%B7%EF%BC%89");
//连接网址
URLConnection conn = url.openConnection();
//创建对象去读取网络数据
BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line;
System.out.println("?<=是忽略前面的内容,只保留后面的内容");
System.out.println("?=是忽略后面的内容,只保留后面的内容");
Pattern pattern = Pattern.compile("(?<=title=\").{1,8}(?=\"></span></a>)");
//每次读取一行
boolean flag = false;
loop:
while ((line = br.readLine()) != null) {
Matcher m = pattern.matcher(line);
while (m.find()) {
if (flag == false) {
flag = true;
continue loop;
}
System.out.println(m.group());
flag = false;
}
}
br.close();
}
}
八.条件爬取
如何查找后面不是11和17的Java字符串?
public class Demo198 {
public static void main(String[] args) {
String str = "Java自从95年问世以来,经历了很多版本,目前企业中用的最多的是Java8和Java11," +
"因为这两个是长期支持版本,下一个长期支持版本是Java17,相信在未来不久Java17也会逐渐登上历史舞台";
System.out.println("使用(?!内容)查找后面不是11和17的Java字符串");
Pattern p = Pattern.compile("Java(?!11|17)");
Matcher m = p.matcher(str);
while (m.find()) {
String strFind = m.group();
System.out.print(strFind + " ");
}
}
}
九.贪婪爬取与非贪婪爬取
1.正则表达式默认是贪婪爬取还是非贪婪爬取?
2.如何使用非贪婪爬取呢?
public class Demo199 {
public static void main(String[] args) {
String str = "abbba";
System.out.println("1.默认尽可能多获取b(贪婪爬取)");
Pattern p1 = Pattern.compile("ab+");
System.out.println("2.尽可能少获取b,在数量控制的后面加个问号(表示匹配但是只捕获尽量少的内容)(非贪婪爬取)");
Pattern p2 = Pattern.compile("ab+?");
Matcher m = p2.matcher(str);
while (m.find()) {
String strFind = m.group();
System.out.print(strFind + " ");
}
System.out.println();
}
}
十.正则表达式在字符串方法中的使用
1.如何使用正则表达式替换字符串中的某些字符? 2.如何利用正则表达式分割字符串?
public class Demo1910 {
public static void main(String[] args) {
String str = "小火龙sa87s4dsa5a551ssa567f8a4s56杰尼龟dsa8dd4a56d4567816dsa7c8xz妙蛙种子";
System.out.println("1.使用字符串中的replaceAll方法替换字符串,这个方法在底层也会创建文本解析器对象matcher去替换字符串");
String str1 = str.replaceAll("\\w+", "vs");
System.out.println(str1);
System.out.println("2.使用字符串中的split方法得到分割后的字符串");
String[] str2 = str.split("\\w+");
for (int i = 0; i < str2.length; i++) {
System.out.print(str2[i] + " ");
}
}
}
十一.利用分组判断字符串中是否具有相同的字符段落
1.用什么符号来表示分组? 2.怎么看分组的组号? 3.如何把组号中的数据拿出来再次使用?
public class Demo1911 {
public static void main(String[] args) {
System.out.println("1.分组:用小括号来表示");
System.out.println("2.组号看小括号的位置,有多少对小括号就有多少组,从左往右排组号,从1开始");
System.out.println("3.\\\\组号:表示把第一组的数据拿出来用一次");
System.out.println("判断字符串的开始字符和结束字符是否一致(一个字符)");
String regex1 = "(.).+\\1";
System.out.println("hahah".matches(regex1));
System.out.println("haha".matches(regex1));
System.out.println("判断字符串的开始字符和结束字符是否一致(多个字符)");
String regex2 = "(.+).+\\1";
System.out.println("hahagagaha".matches(regex2));
System.out.println("hahagagaga".matches(regex2));
System.out.println("判断字符串的开始字符和结束字符是否一致(多个字符,各段字符中的每个字符都相等)");
String regex3 = "((.)\\2*).+\\1";
System.out.println("hahagagaha".matches(regex3));
System.out.println("hahagagahah".matches(regex3));
System.out.println("aaagagagagaaa".matches(regex3));
}
}
十二.案例:把字符串中重复的单个字符替换成一个
如何在组外表示分组?
public class Demo1912 {
public static void main(String[] args) {
String str = "我要学学学学学学学编编编编编编编编编编程程程程程程程程程程程程程";
System.out.println("组外使用$表示分组");
System.out.println(str.replaceAll("(.)\\1+", "$1"));
}
}
十三.捕获分组与非捕获分组
1.什么是捕获分组? 2.什么是非捕获分组? 3.非捕获分组与捕获分组的不同点? 4.那些表示非捕获分组呢?
public class Demo1913 {
public static void main(String[] args) {
System.out.println("1.捕获分组:后续还要使用本组的数据,前面的 \\\\与$都是捕获分组");
System.out.println("2.非捕获分组:分组之后不需要使用本组数据,就仅仅括起来而已");
System.out.println("3.非捕获分组要点就是,不占用组号,不能使用\\\\与$再次表达数据");
System.out.println("4.比如之前用过的(?:)这个是捕获所有数据,但是不是捕获分组。相同的还有(?=)(?<=)(?!)");
System.out.println("在下列案例中不能使用:\\\\1来表示分组");
System.out.println("123456789".matches("(?:.)"));
}
}