前言:
正则表达式的作用:
-
作用一:校验字符串是否满足规则
-
作用二:在一段文本中查找满足要求的内容
一.Pattern类和Matcher类:
1.Pattern类:表示正则表达式
a.因此获取Pattern对象就相当于获取正则表达式的对象;
b.compile方法:获取正则表达式的对象,compile方法的形参就是要写的正则表达式
注:因为compile方法是静态的即被static修饰,所以通过类名.方法名去调用compile方法即Pattern.compile来获取正则表达式的对象(获取获取正则表达式的对象不能new)
matcher方法:形参是要爬取的大串
2.Matcher类:文本匹配器,作用:按照正则表达式的规则去读取字符串(注:从头开始读取),在大串中去找符合匹配规则的子串
a. find方法:
针对形参为空的find方法:拿着文本匹配器从头开始读取,寻找是否有满足规则的子串 如果没有,find方法返回false 如果有,find方法返回true,在底层记录子串的起始索引和结束索引+1
b. group方法:该方法底层会根据find方法记录的索引进行字符串的截取,会把截取的子串进行返回 方法substring(起始索引,结束索引)->包头不包尾,所以上面结束索引加1,上述例子即[0,4)即[0,3]
方法substring:类String里的方法
二.本地爬虫:
题目:
代码:
初级:
package a09RegexDemo;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexDemo1 {public static void main(String[] args) {String str="Java自从95年问世以来,经历了很多版本,目前企业中用的最多的是Java8和Java11," +"因为这两个是长期支持版本,下一个长期支持版本是Java17,相信在未来不久Java17也会逐渐登上历史舞台";
//1.获取正则表达式的对象Pattern p = Pattern.compile("Java[0-9]{0,2}");//也可以是Java\\d{0,2}
//2.获取文本匹配器的对象/* m:文本匹配器的对象str:大串p:规则m要在str中找符合p规则的小串 */Matcher m = p.matcher(str);
//3.拿着文本匹配器从头开始读取,寻找是否有满足规则的子串/*如果没有,find方法返回false如果有,find方法返回true,在底层记录子串的起始索引和结束索引+1 *///比如:str大串中第一个符合规则的子串为一开始的Java,它在大串中的起始索引为0,结束索引加1为3+1即4,此时底层记录0和4boolean b = m.find();
//4.group方法底层会根据find方法记录的索引进行字符串的截取,会把截取的子串进行返回//方法substring(起始索引,结束索引)->包头不包尾,所以上面结束索引加1,上述例子即[0,4)即[0,3]String s1 = m.group();
//5.打印System.out.println(s1);//运行结果为Java,此时找到第一个匹配的子串就会停}
}
中级:
package a09RegexDemo;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexDemo1 {public static void main(String[] args) {String str="Java自从95年问世以来,经历了很多版本,目前企业中用的最多的是Java8和Java11," +"因为这两个是长期支持版本,下一个长期支持版本是Java17,相信在未来不久Java17也会逐渐登上历史舞台";
//1.获取正则表达式的对象Pattern p = Pattern.compile("Java[0-9]{0,2}");//也可以是Java\\d{0,2}
//2.获取文本匹配器的对象/* m:文本匹配器的对象str:大串p:规则m要在str中找符合p规则的小串 */Matcher m = p.matcher(str);
//3.拿着文本匹配器从头开始读取,寻找是否有满足规则的子串/*如果没有,find方法返回false如果有,find方法返回true,在底层记录子串的起始索引和结束索引+1 *///比如:str大串中第一个符合规则的子串为一开始的Java,它在大串中的起始索引为0,结束索引加1为3+1即4,此时底层记录0和4boolean b = m.find();
//4.group方法底层会根据find方法记录的索引进行字符串的截取,会把截取的子串进行返回//方法substring(起始索引,结束索引)->包头不包尾,所以上面结束索引加1,上述例子即[0,4)即[0,3]String s1 = m.group();
//5.打印System.out.println(s1);//运行结果为Java,此时找到第一个匹配的子串就会停
//第二次再调用find方法,就会继续读取后面的内容/*之前已读取到4索引上,此时继续从4索引开始读取*///读取到第二个满足要求的子串,方法会继续返回true,并把第二个子串的起始索引和结束索引加1进行记录b=m.find();
//第二次调用group方法的时候,会根据find方法记录的索引再次截取子串String s2=m.group();
//打印System.out.println(s2);//运行结果为Java8,此时找到第二个匹配的子串就会停}
}
终极:用循环找出所需要的全部子串
package a09RegexDemo;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexDemo1 {public static void main(String[] args) {String str="Java自从95年问世以来,经历了很多版本,目前企业中用的最多的是Java8和Java11," +"因为这两个是长期支持版本,下一个长期支持版本是Java17,相信在未来不久Java17也会逐渐登上历史舞台";
//1.获取正则表达式的对象Pattern p = Pattern.compile("Java[0-9]{0,2}");//也可以是Java\\d{0,2}//2.获取文本匹配器的对象/*拿着m去读取str,找符合p规则的子串*/Matcher m = p.matcher(str);//3.核心:利用循环读取/*由于不知道符合规则的子串有几个,因此可用while循环*//* m.find()作为循环条件,一直读取,读取到就返回true,之后进行下一轮的读取,一旦读取到false,就说明大串中没有要找的子串了,查找停止 */while (m.find()){String s = m.group();System.out.println(s);}}
}
三.网络爬虫:
1.类URL:
a.针对只有一个形参的构造方法:该构造方法的形参可以是要爬取的网址,抛出异常MalformedURLException;
b.URL对象即网址对象;
c.方法openConnection:用来打开网址,返回类URLConnection,相当于打开网址后创建网址对象
2.类URLConnection:用来连接创建的网址对象,注:要保证网址畅通
方法getInputStream:返回的数据类型为InputStream
3.类InputStreamReader:
构造方法:一共有4个,每个构造方法的形参的类型都有InputStream
4.类BufferedReader:
a.方法readLine:返回String型,在读取的时候每次读取一整行,从第一行开始,注:不是所有信息
b.方法close:
5.代码演示:
网课中:
实操:
package a09RegexDemo;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
public class RegexDemo2 {public static void main(String[] args) throws IOException {/*需求:爬取链接中的数据*/
//1.创建一个URL对象URL url = new URL("https://dasai.lanqiao.cn/??/");
//2.连接上这个网址/*注:要保证网址畅通*/URLConnection conn = url.openConnection();
//3.创建一个对象去读取网络中的数据BufferedReader br = new BufferedReader( new InputStreamReader( conn.getInputStream() ));
String line;
//4.循环进行读取/*在读取的时候每次读取一整行,从第一行开始,注:不是所有信息*/while ( (line=br.readLine()) != null){System.out.println(line);}
//5.关闭br.close();}
}
四.练习:
题目:
代码:
package a09RegexDemo;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexDemo3 {public static void main(String[] args) {String s="来黑马程序员学习Java," +"电话:18512516758,18512508907" +"或者联系邮箱:boniu@itcast.cn," +"座机电话:01036517895,010-98951256," +"邮箱:bozai@itcast.cn," +"热线电话:400-618-9090,400-618-4000,4006184000,4006189090";
//手机号的正则表达式为1[3-9]\\d{9}//邮箱的正则表达式为\\w+@[\\w&&[^_]]{2,6}(\\.[a-zA-Z]{2,3}){1,2}//座机电话的正则表达式为0\\d{2,3}-?[1-9]\\d{4,9}//热线电话的正则表达式400-?[1-9]\\d{2}-?[1-9]\\d{3}
String regex="(1[3-9]\\d{9})" +"|(\\w+@[\\w&&[^_]]{2,6}(\\.[a-zA-Z]{2,3}){1,2})" +"|(0\\d{2,3}-?[1-9]\\d{4,9})" +"|(400-?[1-9]\\d{2}-?[1-9]\\d{3})"; // |表示或,代表满足括号中的一个即可,|左右不能有空格
//1.获取正则表达式的对象Pattern p = Pattern.compile(regex);
//2.获取文本匹配器的对象/*利用m去读取s,会按照p的规则找里面的小串*/Matcher m = p.matcher(s);
//3.利用循环获取每一个数据while (m.find()){String str = m.group();System.out.println(str);}
}
}