正则表达式(就是一种规则)与基础爬虫匹配

正则表达式(就是一种规则)与基础爬虫匹配

复习下之前的方法:

str.startswitch(“0”) 判断字符串是不是以0开头

Character.isDigit(char) 判断一个char类型字符是否是数字

1、⭐小例子

设定注册qq号必须为6-20位,且必须是数字,0不能开头
原始解法:
public static void main(String[] args) {
    String qq = "243523523523523501234567890";
    System.out.println(checkQQ(qq));
}

private static boolean checkQQ(String qq) {
    //  长度判断
    if (qq.length() < 0 || qq.length() > 20) {
        return false;
    }
    //  如果第一个是0就返回false
    if (qq.startsWith("0")) {
        return false;
    }
    //  判断是否都是数字
    for (int i = 0; i < qq.length(); i++) {
        if (qq.charAt(i)<'0'||qq.charAt(i)>'9'){
            return false;
        }
    }
    return true;
}
正则表达式解法str.matches(“规则”)
public static void main(String[] args) {
    String qq = "24352352352390";
    							//  第一位:1-9  \\d必须是数字 {start,end}数字个数的范围,最多有end个数,最少start位
    							//	意思就是 第一位只能是1-9的数字  后面只能是5-19个数字
    System.out.println(qq.matches("[1-9]\\d{5,19}"));
}

2、正式介绍

⭐API帮助文档pattern

public static void main(String[] args) {
    /*
        验证手机号码          13112345678 13712345667 13945679927 139456799271
        验证座机电话号码       020-2324242 02122442 027-42424 0712-3242434
        验证邮箱号码          3232323@qq.com zhangsan@itcast.cnn dlei9@163.com dleieee9@pci.com.cn
    */
    //  第一部分@的左边:\w+
    //                可以是一个或者多个的字母数字下划线
    //  第二部分:@      :这个符号有且仅有一次
    //  第三部分@的右边:
    //         3.1 点的左边:[\\w&&[^_]]{2,6} :可以是数字和字母不能是下划线2位到6位
    //         3.2 点的必须有    \\.
    //         3.3 点的右边:[a-zA-Z]{2,3} 可以是大小写英文2到3位
    //         注意:这里可能会出现1到两次的域名例如:dleieee9@pci.com.cn分组处理用(){1,2}:(\.[a-zA-Z]{2,3}){1,2}
    String emailRegex = "\\w+@[\\w&&[^_]]{2,6}(\\.[a-zA-Z]{2,3}){1,2}";
    String email1 = "3232323@qq.com";
    String email2 = "zhangsan@itcast.cnn";
    String email3 = "dlei9@163.com";
    String email4 = "dleieee9@pci.com.cn";
    System.out.println(email1.matches(emailRegex));
    System.out.println(email2.matches(emailRegex));
    System.out.println(email3.matches(emailRegex));
    System.out.println(email4.matches(emailRegex));
    System.out.println("------------------------------------------");
    //  ?代表0次或者1次
    //  一、区号    0\d{2,3}
    //            0:第一位必须是0;
    //      \d{2,3}:从第二位开始可以是任意数字,2到3位
    // 二、-       出现一次或者0次用?
    // 三、号码第一位不能0开头,第二位开始可以是任意数字,长度为5-10位
    String telephoneNumberRegex = "0\\d{2,3}-?[1-9]\\d{4,9}";
    String telephoneNumber1 = "020-2324242";
    String telephoneNumber2 = "02122442";
    String telephoneNumber3 = "027-42424";
    String telephoneNumber4 = "0712-3242434";
    System.out.println(telephoneNumber1.matches(telephoneNumberRegex));
    System.out.println(telephoneNumber2.matches(telephoneNumberRegex));
    System.out.println(telephoneNumber3.matches(telephoneNumberRegex));
    System.out.println(telephoneNumber4.matches(telephoneNumberRegex));
    System.out.println("------------------------------------------");
    String iphoneNumberRegex = "1[3-9]\\d{9}";
    String iphoneNumber1 = "13112345678";
    String iphoneNumber2 = "1945679927";
    String iphoneNumber3 = "12112345678";
    String iphoneNumber4 = "23112345678";
    System.out.println(iphoneNumber1.matches(iphoneNumberRegex));//true
    System.out.println(iphoneNumber2.matches(iphoneNumberRegex));//false
    System.out.println(iphoneNumber3.matches(iphoneNumberRegex));//false
    System.out.println(iphoneNumber4.matches(iphoneNumberRegex));//false
}

3、插件 idea中点击setting 进入plugins 搜索any-rule

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1LVKWN1E-1673759570549)(E:\Java\Java笔记\image\1673676804109.jpg)]

右击字符串显示anyRule出现各种规则,然后根据所得进行修改即可

1673676871902

4、例题

public static void main(String[] args) {
    //  例题:用户用的正则表达式:字母数字下划线4-16位
    String regex1="\\w{4,16}";
    System.out.println("zhangsan123".matches(regex1));      //true
    System.out.println("_23276".matches(regex1));           //true
    System.out.println("weasd_wead222".matches(regex1));    //true
    //  身份证号正则表达式:18位,前17位是任意数字,最后一位是数字或者是X或者x
    System.out.println("=============================");
    String regex2="[1-9]\\d{16}[Xx\\d]";
    String regex3="[1-9]\\d{16}(\\d|((?i)x))";//忽略x的大小写
    System.out.println("374535198802123012".matches(regex2));
    System.out.println("37142512980214502X".matches(regex2));
    System.out.println("=============================");
    // 忽略大小写(?i)abc
    System.out.println("aBC".matches("(?i)abc"));//true
    System.out.println("374535198802123012".matches(regex3));
    System.out.println("37142512980214502X".matches(regex3));
    String ID="410801 1993 02 28 457x";
    // 身份证号码的严格校验
    // 前面6位,省份,市区,派出所等信息 第一位不能是0,后面5位是任意数     [1-9]\\d{5}
    // 年的前半:18,19,20                                        (18|19|20)
    // 年的后半:任意数字出现两次                                    \\d{2}
    // 月份:第一位是0第二位就是任意数字,第一位是1第二位就是0-2          ((0\\d)|(1[0-2]))
    // 日:0~31                                                  (([0][1-9])|([1-2][\d])|(3[0-1]))
    // 最后4位:前3位就是任意数字,最后一位就是x或者X或者任意数字          \d{3}(\d|((?i)x))
    String  regex4="[1-9]\\d{5}(18|19|20)\\d{2}((0[1-9])|(1[0-2]))(([0][1-9])|([1-2][\\d])|(3[0-1]))\\d{3}(\\d|((?i)x))";
    System.out.println("41080119930228457x".matches(regex4));
}

常用符号

在这里插入图片描述


在这里插入图片描述

(?i)xxxx;忽略xxxx的大小写

String txt="Xx";
System.out.println(txt.matches("(?i)xx"))//true
System.out.println(txt.matches("(?i)Xx"))//true
System.out.println(txt.matches("(?i)XX"))//true

xxx(?=bb);?代表前面的xxx =表示xxx后面要跟随的数据bb;但是获取的时候只获取前半部分也就是 xxx

String txt="abc1是abc的第一部分,abc2是abc的第二部分";
Pattern compile = Pattern.compile("abc(?=1|2)");
Matcher matcher = compile.matcher(txt);
while (matcher.find()) {
    System.out.println(matcher.group());
}
//	输出结果:爬取的是后面带有1或者2的数据 并且只显示前半部分
abc
abc

xxx(?:bb);?代表前面的xxx =表示xxx后面要跟随的数据bb;但是获取的时候全部获取

String txt="abc1是abc的第一部分,abc2是abc的第二部分";
Pattern compile = Pattern.compile("abc(?:1|2)");
Matcher matcher = compile.matcher(txt);
while (matcher.find()) {
    System.out.println(matcher.group());
}
//	输出结果:爬取的是后面带有1或者2的数据,并且显示全部
abc1
abc2

xxx(?!bb);xxx后面不是bb的数据,只显示前半部分

String txt="abc1是abc的第一部分,abc2是abc的第二部分";
Pattern compile = Pattern.compile("abc(?!1|2)");
Matcher matcher = compile.matcher(txt);
while (matcher.find()) {
    System.out.println(matcher.group());
}
//	输出结果:爬取的不是后面带有1和2的abc数据,并且只显示前半部分
abc
abc

在这里插入图片描述

5、爬虫案例

解析

public static void main(String[] args) {
    String txt="Java自从95年问世以来,经历了很多版本,目前企业中用的最多的是Java8和Java11,因为这两个是长期支持版本," +
            "下一个长期支持版本是Java17,相信在未来不久Java17也会逐渐登上历史舞台";
    //  Pattern:表示正则表达式
    //  Matcher:文本匹配器,作用按照正则表达式的规则去读取字符串,从头开始读取。
    //  在大串中去找符合匹配规格的子串

    //  获得一个正则表达式的对象
    Pattern p = Pattern.compile("Java\\d{0,2}");
    //  获得文本匹配器的对象
    //  matcher:文本匹配器的对象
    //  txt:就是大串
    //  p就是规则
    //  matcher需要在txt中去找符合规则的子串
    Matcher matcher = p.matcher(txt);
    //  拿着文本匹配器去从头开始查找,如果找到就返回true 没找到返回false
    //  底层会记录字串的:起始索引和结束索引+1
    boolean b1 = matcher.find();
    //  该方法会根据find()方法底层记录的索引去截取字符串
    //  其实底层调用的subString(起始,结束)包头不包尾  :subString(0,4) ->Java
    String group1 = matcher.group();
    System.out.println(group1);
    //  去当前位置去寻找第二个符合规则的字符串 记录索引
    boolean b2 = matcher.find();
    String group2 = matcher.group();
    System.out.println(group2);
    System.out.println(b2);
}

正式书写:打印出所有符合正则表达式的内容

public static void main(String[] args) {
    String txt = "Java自从95年问世以来,经历了很多版本,目前企业中用的最多的是Java8和Java11,因为这两个是长期支持版本," +
            "下一个长期支持版本是Java17,相信在未来不久Java17也会逐渐登上历史舞台";
    conformToRegex(txt);
}

public static void conformToRegex(String txt) {
    Pattern regex = Pattern.compile("Java\\d{0,2}");
    Matcher txtMatcher = regex.matcher(txt);
    while (txtMatcher.find()) {
        System.out.println(txtMatcher.group());
    }
}
//	输出结果
Java
Java8
Java11
Java17
Java17

爬虫复习例子

public static void main(String[] args) {
    //  需求:把下面文本中的电话,邮箱,手机号,热线都爬取出来。
    String message = "来黑马程序员学习Java\n" +
            "电话:18512516758,18512508907或者联系邮箱: boniu@itcast.cn,\n" +
            "座机电话: 01036517895,010-98951256\n" +
            "邮箱: bozai@itcast.cn\n" +
            "热线电话: 400-618-9090,400-618-4000,4006184000,4006189090";
    //  爬取电话号码
    findIphoneNumber(message);
    //  爬取邮箱
    findEmail(message);
    //  爬取座机号码
    findTeleNumber(message);
    //  爬取热线
    findHotLine(message);

}

private static void findHotLine(String message) {
    Pattern hotLinePattern = Pattern.compile("([1-9]\\d{2}-?){2}[1-9]\\d{3}");
    Matcher matcher = hotLinePattern.matcher(message);
    while (matcher.find()){
        System.out.println(matcher.group());
    }
}

private static void findTeleNumber(String message) {
    Pattern teleNumberPattern = Pattern.compile("0\\d{2,3}-?[1-9]\\d{7}");
    Matcher matcher = teleNumberPattern.matcher(message);
    while (matcher.find()){
        System.out.println(matcher.group());
    }
}

private static void findEmail(String message) {
    Pattern emailPattern = Pattern.compile("\\w+@[\\w&&[^_]]{2,6}(\\.(cn|com)){1,2}");
    Matcher matcher = emailPattern.matcher(message);
    while (matcher.find()){
        System.out.println(matcher.group());
    }

}

private static void findIphoneNumber(String message) {
    Pattern iphoneNumberPattern = Pattern.compile("1[3-9]\\d{9}");
    Matcher matcher = iphoneNumberPattern.matcher(message);
    while (matcher.find()){
        System.out.println(matcher.group());
    }
}

带有条件的爬虫

public static void main(String[] args) {
    String txt = "Java自从95年问世以来,经历了很多版本,目前企业中用的最多的是Java8和Java11,因为这两个是长期支持版本," +
            "下一个长期支持版本是Java17,相信在未来不久Java17也会逐渐登上历史舞台";

    //  爬取java后面有版本号,但是还不显示版本号的数据 Java、Java、Java
    findJava(txt);
    //  爬取java后面有版本号,并且显示版本号 例如:Java8、Java11、Java17、Java17
    findJava1(txt);
    //  爬取除了版本号为:Java8、Java11、Java17的Java数据 例如:Java
    findJava2(txt);
}

private static void findJava2(String txt) {
    Pattern compile = Pattern.compile("(?i)java(?!8|11|17)");
    Matcher matcher = compile.matcher(txt);
    while (matcher.find()) {
        System.out.println(matcher.group());
    }
}

private static void findJava1(String txt) {
    Pattern compile = Pattern.compile("(?i)Java(?:\\d{1,2})");
    Matcher matcher = compile.matcher(txt);
    while (matcher.find()) {
        System.out.println(matcher.group());
    }
}

private static void findJava(String txt) {
    //  注释:  xxx(?=) ->这里的?代表前面的xxx,=后面是xxx后面要拼接的字符串
    //  这里的意思就是Java8/Java11/Java17都可以  但是不显示后面的
    Pattern compile = Pattern.compile("(?i)Java(?=8|11|17)");
    Matcher matcher = compile.matcher(txt);
    while (matcher.find()) {
        System.out.println(matcher.group());
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值