前言:
正则表达式的作用:
-
作用一:校验字符串是否满足规则
-
作用二:在一段文本中查找满足要求的内容
一.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里的方法
二.本地爬虫:
题目:
代码:
初级:
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和4
boolean b = m.find();
//4.group方法底层会根据find方法记录的索引进行字符串的截取,会把截取的子串进行返回
//方法substring(起始索引,结束索引)->包头不包尾,所以上面结束索引加1,上述例子即[0,4)即[0,3]
String s1 = m.group();
//5.打印
System.out.println(s1);//运行结果为Java,此时找到第一个匹配的子串就会停
}
}
中级:
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和4
boolean 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,此时找到第二个匹配的子串就会停
}
}
终极:用循环找出所需要的全部子串
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规则的子串*/
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.代码演示:
网课中:
实操:
java
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();
}
}
四.练习:
题目:
代码:
java
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);
}
}
}