【了解Java正则表达式】文本校验及网络信息爬取

一、概述

正则表达式:用来描述或者匹配一系列符合某个语句规则的字符串

        作用:1)校验字符串是否满足规则

                   2)在一段文本中查找满足要求的内容

二、正则表达式的常见形式

1.字符类(只匹配一个字符)

[a,b,c]只能a,b,c
[^a,b,c]除了a,b,c以外的任何字符
[a-zA-Z]大小字母a~z及A~Z
[a-d[m-p]]a~d或m~p
[a-z&&[def]]a~z与d,e,f的交集,等价于:d或e或f
[a-z&&[^bc]]a~z与非bc的交集,等价于:a或d~z

2.预定义字符(只匹配一个字符)

.任何字符
\d一个数字,等价于[0-9]
\D非数字,等价于[^0-9]
\s一个空白字符,等价于[\t\n\x\f\r]
\S非空白符,等价于[^\s]
\w包含数字、英文、下划线,等价于[a-zA-Z_0-9]
\W表示不是由数字、英文、下划线组成

3.数量词

X?X,零次或一次
X*X,零次,一次或多次

X+

X,一次或多次
X{n}X,正好n次
X{n,}X,至少n次
X{n,m}X,在n~m次

示例:借助正则表达式匹配的判断函数matches简单阐述

  • public boolean matches(String regex):返回true表示当前验证的字符串匹配正则表达式的描述
package ZhengZe;

public class RegexDemo {

	public static void main(String[] args) {
		//  \ 转义字符:改变后面那个字符原本的含义
		//若想要以字符串的形式打印一个双引号,需要转义字符改变"原本的含义(原本表示引用)
		System.out.println("\"");   //"
		
		// .表示任意一个字符
		System.out.println("你".matches(".."));   //false
		System.out.println("你a".matches(".."));   //true
		
		//  \\d只能是任意的一位字符
		//   第一个\表示转义字符;\d表示数字符
		System.out.println("a".matches("\\d"));   //false
		System.out.println("3".matches("\\d"));   //true
		System.out.println("333".matches("\\d"));   //false
		
		//  \\w只能是任意的一位单词字符 [a-zA-Z_0-9]
		System.out.println("a".matches("\\w"));   //true
		System.out.println("3".matches("\\w"));   //true
		System.out.println("333".matches("\\w"));   //false
		
		//  \\W 非单词字符
		System.out.println("你".matches("\\W"));   //true
		
		//**********以上正则匹配只能校验单个字符**********//
		

		// 必须是数字 字母 下划线,至少6位
		System.out.println("a244_bcf".matches("\\w{6,}"));   //true
		System.out.println("a24f".matches("\\w{6,}"));   //false
		
		//必须是数字和字符,必须是4位
		System.out.println("23dF".matches("[a-zA-Z0-9]{4}"));   //true
		System.out.println("23dF".matches("[\\w&&[^_]]{4}"));   //true
	}

}

三、正则表达式的应用

1.验证手机号码、座机号码、邮箱号码、身份证号的格式是否正确

package ZhengZe;
//验证手机号码、座机号码、邮箱号码、身份证号的格式是否正确

public class RegexDemo01 {

	public static void main(String[] args) {
		// 验证手机号码  13112345678  13712345667 139456790271
		//将手机号码的格式分为三部分
		//1)1 表示手机号码只能以1开头;  2)[3-9]表示第二位只能是3-9之间;  3)\\d{9}表示任意数字可以出现9次,也只能出现9次(一共只有11位)
		String regex1 = "1[3-9]\\d{9}";
		System.out.println("13112345678".matches(regex1));   //true
		System.out.println("13712345667".matches(regex1));   //true
		System.out.println("139456790271".matches(regex1));   //false

		
		// 验证座机号码  020-2324242  02122442 0712-3242434 027-42424
		//将手机号码的格式分为三部分
		//1)区号 :0\\d{2,3},区号一定以0开头,从第二位开始可以是任意数字,0后面有2到3位
		//2)- :-?, 次数:0或1次
		//3)号码: [1-9]\\d{4,9},  号码的第一位不能以0开头([1-9]),从第二位开始可以是任意数字,号码的总长度:5-10位(\\d{4,9})
		String regex2 = "0\\d{2,3}-?[1-9]\\d{4,9}";
		System.out.println("020-2324242".matches(regex2));   //true
		System.out.println("02122442".matches(regex2));   //true
		System.out.println("0712-3242434".matches(regex2));   //true
		System.out.println("027-42424".matches(regex2));   //true
		
		//验证邮箱号码    323232445@qq.com  java1314@163.com   dlei009@pci.com.cn   zzz@itcast.cn
		//将邮箱的格式分为三部分
		//1)@的左边 :\\w+,任意的数字字母下划线,出现一次就可以了
		//2)@:必须出现,且只能出现一次
		//3)@的左边 :  .的左边[\\w&&[^_]]{2,6},任意的字母或者数字,总共出现2-6次(此时不能出现下划线);
		//           .的右边[a-zA-Z]{2,3},大小写字母只能出现2-3位
		//			 (\\.[a-zA-Z]{2,3})括号表示分组,这一组出现1或2次
		String regex3 = "\\w+@[\\w&&[^_]]{2,6}(\\.[a-zA-Z]{2,3}){1,2}";
		System.out.println("323232445@qq.com".matches(regex3));   //true
		System.out.println("java1314@163.com".matches(regex3));   //true
		System.out.println("dlei009@pci.com.cn".matches(regex3));   //true
		System.out.println("zzz@itcast.cn".matches(regex3));   //true
		
		
		//简单校验身份证号码
		//18位,前17位任意数字,最后一位可以是大写或小写x(有以下三种表示方式)
		//String regex4 = "[1-9]\\d{16}(\\d|X|x)";//最后一位用分组中“或”的关系表示
		//String regex4 = "[1-9]\\d{16}[\\dXx]";
		String regex4 = "[1-9]\\d{16}(\\d|(?i)x)";//(?i)x表示x不区分大写或者小写
		System.out.println("41080119930225457x".matches(regex4));   //true
	}

}

2.利用正则表达式爬取本地信息

有如下文本,按照要求爬取数据:
    Java自从95年问世以来,经历了很多版本,母亲企业中用的最多的是Java8和Java11,
    因为这两个是长期支持版本,下一个长期支持版本是Java17,相信在未来不久Java17也会逐渐登上历史的舞台。

 要求:找出里面的所有JavaXX

package Zhengze;
//利用正则表达式爬取本地信息

//Pattern类:表示正则表达式
//Matcher类:文本匹配器,按照正则表达式的规则去读取字符串,从头开始读取
//		在整个字符串去找符合匹配规则的子串
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexDemo02 {

	public static void main(String[] args) {
		
		String str = "Java自从95年问世以来,经历了很多版本,母亲企业中用的最多的是Java8和Java11,"+
		"因为这两个是长期支持版本,下一个长期支持版本是Java17,相信在未来不久Java17也会逐渐登上历史的舞台。";
		
		
		//method1(str);//最初的编程思路,能够获得前两个JavaXX子串,要获得所有子串,使用循环语句
		
		//1.获取正则表达式的对象
		Pattern p = Pattern.compile("Java\\d{0,2}");
		
		//2.获取文本匹配器的对象:m要在str中找符合p规则的字串
		Matcher m = p.matcher(str);
		
		//3.利用循环获取
		while(m.find()) {
			String s = m.group();
			System.out.println(s);
		}

	}
	
	private static void method1(String str) {
		//1.获取正则表达式的对象
		Pattern p = Pattern.compile("Java\\d{0,2}");//Java后附0~2位数字
		//2.获取文本匹配器的对象:m--文本匹配器的对象;str--整个字符串;p--规则
		//即  m要在str中找符合p规则的字串
		Matcher m = p.matcher(str);
		
		
		//拿着文本匹配器从头开始读取,寻找是否有满足规则的子串:如果没有,方法返回false;如果有,返回true,在底层记录子串的起始索引和结束索引+1
		//而subString(起始索引,结束索引)这一方法包头不包尾,即对于子串[0,4],只存储索引0~3
		boolean b = m.find();
		
		//方法group:根据find方法记录的索引进行字符串的截取,把截取的子串进行返回
		String s1 = m.group();
		System.out.println(s1);
		
		//3.第二次再次调用find方法的时候,会继续读取后面的内容
		//读取到第二个满足要求的子串,方法会继续返回true,并把第二个子串的起始索引和结束索引+1,进行记录
		b = m.find();
		
		//第二次调用group方法,会根据find方法记录的索引再次截取子串
		String s2 = m.group();
		System.out.println(s2);
	}
}

 3.利用正则表达式爬去(所需格式的)网络信息

package Zhengze;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

//利用正则表达式爬去网络信息(这是一个列有身份证号的网址)
//把链接:"https://www.qindaosou.com/baike/20210411825044.html"中所有的身份证号码全都爬取出来

public class RegexDemo03 {

	public static void main(String[] args) throws IOException {
		
		//创建一个网址对象
		URL url = new URL("https://www.qindaosou.com/baike/20210411825044.html");
		//连接上这个网址
		//细节:保证网络是畅通的
		URLConnection conn = url.openConnection();
		//创建一个对象去读取网络中的数据
		BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
		
		String line;
		
		
		//获取正则表达式的对象pattern
		String regex = "[1-9]\\d{17}";
		Pattern pattern = Pattern.compile(regex);
		
		//在读取的时候每次读一整行
		while((line = br.readLine())!=null) {
			
			//拿着文本匹配器的对象matcher按照pattern的规则去读取当前这一行信息
			Matcher matcher = pattern.matcher(line);
			while(matcher.find()) {
				System.out.println(line);
			}
			

			//System.out.println(line);
		}

		br.close();
	}

}

4.贪婪爬取和非贪婪爬取

有如下文本,按照要求爬取数据
    Java自从95年问世以来,abbbbbbbaaaaaaaaaaa,经历了很多版本,目前企业中用的最多的是Java8和Java11.
    因为这两个是长期支持版本,下一个长期支持版本是Java17,相信在未来不久Java17也会逐渐登上历史的舞台。
    
    要求1:按照ab+的方式爬取ab,b尽可能多获取
    要求2:按照ab+的方式爬取ab,b尽可能少获取
    
        只写+和*表示贪婪匹配
        +?非贪婪匹配
         *?非贪婪匹配

        Java当中,默认的就是贪婪爬取;如果我们在数量词+/ * 的后面加上问号,那么此时就是非贪婪爬取

package Zhengze;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

//贪婪爬取和非贪婪爬取
//贪婪爬取:在爬取数据的时候尽可能的多获取数据;非贪婪爬取:在爬取数据的时候尽可能的少获取数据

public class RegexDemo04 {

	public static void main(String[] args) {
		String str = "java自从95年问世以来,abbbbbbbaaaaaaaaaaa"+
				"经历了很多版本,目前企业中用的最多的是JAva8和JAVa11,"+
				"因为这两个是长期支持版本,下一个长期支持版本是JAVA17,相信在未来不久Java17也会逐渐登上历史的舞台。";
		
		String regex = "ab+";   //贪婪爬取
		//String regex = "ab+?";  //非贪婪爬取
		
		Pattern p = Pattern.compile(regex);
		Matcher m = p.matcher(str);
		
		while(m.find()) {
			System.out.println(m.group());
		}
	}

}

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

锅小白

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值