java正则表达式 及应用场景爬虫,捕获分组非捕获分组

news2025/6/24 15:35:46

正则表达式

通常用于校验 比如说qq号 看输入的是否符合规则就可以用这个

public class regex {
    public static void main(String[] args) {
        //正则表达式判断qq号是否正确
        //规则 6位及20位以内  0不能再开头  必须全是数子

        String qq="1234567890";
        System.out.println(qq.matches("[1-9]\\d{5,19}"));
        //在正则表达式中 第一个表示不能以0开头所以写了1到9满足就行  第二个
        //写了\\d表示全是数字就行
        //第三写了5到19 因为规则是6位及20位以内.正则表达式开头不算算后面  后面是5到19位

    }
}

正则表达式还有一个作用在一段文本中查找满足要求的内容

在这里插入图片描述
注意一个[]大括号只匹配一个字符
在这里插入图片描述


在这里插入图片描述
下面是知识引入在这里插入图片描述

所以总结\在java中有特殊含义. 口诀:两个\才表示一个
在这里插入图片描述

正则表达式校验多个字符

在这里插入图片描述
X表示任意字符
在这里插入图片描述

练习

public class test {
    public static void main(String[] args) {
        //验证手机号码
        //拿到一个正确的数从左到右一次去写
        //13103719499  13103123499  13103716212


        //第一部分手机号码以1开头
        //第二个数字根据常识是3到9
        //第三个往后的都是任意数字


        String regex1="1[3-9]\\d{9}";

        System.out.println("13103719499".matches(regex1));//true
        System.out.println("13103123499".matches(regex1));//true
        System.out.println("131037162121".matches(regex1));//false
        System.out.println("_____________________");



        //座机号码
        //020-2324252 02122442 027-42423  0712-3242434

        //思路
        //以0开头
        //后面是任意数字两位或者三位
        //-是只能出现1次或0次  用?表示
        //号码不能以0开头  所以携程[1-9]
        //最后面是任意数字   号码总长是5到10位
        String regex2="0\\d{2,3}-?[1-9]\\d{4,9}";

        System.out.println("020-2324252".matches(regex2));
        System.out.println("02122442".matches(regex2));

        System.out.println("------------------------");

        //邮箱号码
        //3231231@qq.com   zhangsan@dawd.cnn  dled0011@163.com   dlei12321@pci.com.cn

        //思路
        //第一部分
        //@左边可以是任意数字字母或者包含下划线  \w+  这个加号表示出现一次或者多次
        //第二部分 @ 只能一次
        //第三 3.1  可以是任意数字字母或者不包含下划线[\\w&&[^_]{2,6} 出现2到6次
        //3.2   . \\.   第一个\是告诉java编译器的第二个\是告诉正则表达式的 因为 . 在正则表达式中有特殊含义 所以这里要转译两次
        //3.3   大小写字母都可以 出现 2 到3次  [a-zA-Z]{2,3}
        //我们把3.2 3.3 看成一组括起来让他们出现1 次或2次就组成了dlei12321@pci.com.cn
        String regex3="\\w+@[\\w&&[^_]]{2,6}(\\.[a-zA-Z]{2,3}){1,2}";
        System.out.println("3231231@qq.com".matches(regex3));

        System.out.println("dlei12321@pci.com.cn".matches(regex3));

      
    }

}

注意"\\. 第一个\是告诉java编译器的第二个\是告诉正则表达式的 因为 . 在正则表达式中有特殊含义 所以这里要转译两次

练习2

public class test2 {
    public static void main(String[] args) {
        //要求以验证用户名是否满足要求
        //要求 大小写字母 数字下划线一共4到16位
        //dawd1231_dawd
        String regex1="\\w{4,16}";
        System.out.println("daw1231_dad".matches(regex1));

        //判断身份证号是否满足要求
        //简单要求 18位 前17位是任意数字 最后一位可以是大写或者小写x
        String regex2="[1-9]\\d{16}(\\d|x|X)";

        System.out.println("410922200206061619".matches(regex2));
        System.out.println("41092220020606169X".matches(regex2));


        System.out.println("______________________");
        //忽略大小写的方式

        String regex3="(?i)abc";
        System.out.println("abC".matches(regex3));//true
        System.out.println("ABC".matches(regex3));//true



        //身份证号码严格校验
        //410922  2002  0606  1619
        //前六位 第一位不能是0  后面5位是任意数字 [1-9]\\d{5}
        //年份前两位现在只有18  19 20    (18|19|20)
        //年后半段任意数字                 \\d{2}
        //月份01-09  10-12                (0[1-9]|1[0-2])
        //日期 01-09  10-19  20-29  30 31    (0[1-9]|[12]\\d|3[01])
        //前三位是任意数字 最后一位可以是大小写的X       \\d{3}[\\dXx]

        //[01]表示可以是0 也可以是1
        String regex4="([1-9]\\d{5})(18|19|20)\\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\\d|3[01])\\d{3}[\\dXx]";

        System.out.println("41092220000606161X".matches(regex4));
    }
}

正则表达式小结

在这里插入图片描述
在这里插入图片描述

所以在java中书写\.就需要先转义\就是\\.而其他语言中就可以直接为\.
因为java编译的时候,会把两个\\看成一个\,而我们写\d,\d是特殊字符不需要转义

爬虫

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

        //第一步获取正则表达式 括号里表示需要爬取的条件
        Pattern p = Pattern.compile("java\\d{0,2}");
        //用上面的爬取条件 获取文本匹配器对象
        //传入str是要查的文章内容
        //拿m读取str找到 找到符合p的子串
        Matcher m = p.matcher(str);
        
        //拿着文本匹配器从头开始读取找到满足规则的子串
        //如果没有返回false
        //底层记录字串的起始索引和结束索引加1
        //0,4  这个是
        boolean b = m.find();
        
        
        //根据find方法记录的索引进行字符串的截取
        //用到subString方法(起始索引,结束索引)包头不包尾  这就是为什么find最后要记录索引了
        //会把街区的小串返回
        String s = m.group();
        System.out.println(s);

普通写法 但是这种一次只能一个

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

        //1.获取正则表达式
        Pattern p = Pattern.compile("Java\\d{0,2}");
        //2.获取文本匹配器的对象
        Matcher m = p.matcher(str);
        //3.利用循环获取
        while (m.find()) {//循环的意思是当find没有找完的情况下不会停止.如果没有满足条件的就会停止

            String s = m.group();//他会将find找的返回的索引返回字符串
            System.out.println(s);

循环写法

爬取网络上信息

public class internetPaQu {
    public static void main(String[] args) throws IOException {

        //爬取网络上的信息 比如是身份证号


        //创建一个url对象 可以理解为存网址的
        URL url=new URL("https://520zuowens.com/xiaoxue/1122109.html");

        //连接上这个网址
        URLConnection conn = url.openConnection();
        //创建一个对象读取网络中的信息
        BufferedReader br=new BufferedReader(new InputStreamReader(conn.getInputStream()));
        String line;

//每次读一整行 只要没读完就不停下来
        while((line= br.readLine())!=null){
            System.out.println(line);
        }
        //br.close();
    }
}

接下来是待条件的读取 我只想要网址中身份证号

public class pachong2 {
    public static void main(String[] args) {
        String index = "手机号信息:13333333333 15555555555 18888888888" +
                "邮箱信息:12@qq.com  s123@163.com sdjkaxh@pci.com.cn 400-100-3233" +
                "座机号码: 021-1584654 0215412111 0214511111"+"热线电话:400-618-9090,400-231-2344,4006182323";

        String regex = "(0\\d{2,6}-?\\d{5,20})|(\\w{1,30}@[0-9a-zA-Z]{2,20}(\\.[0-9a-zA-Z]{2,20}){1,2})" +
                "|(1[3-9]\\d{9})|(400-?\\d{3,9}-?\\d{3,9})|400-?[1-9]\\d{2}-?[1-9]\\d{3}";

//这一步是获取正则表达式
        Pattern pattern = Pattern.compile(regex);
//这一步是把文本管理器读取index 根据prttern规则
        Matcher m = pattern.matcher(index);
        while(m.find()){
            System.out.println(m.group());

        }


    }

带条件的爬取

在这里插入图片描述

   public static void main(String[] args) {

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

        //需求1 爬取版本号为8 11 17的java文本  但只要java 不显示版本号


        //?可以理解为是java
        //=后边是java后面跟随的数据 但是获取的时候只要前半部分
        String regex1="((?i)java)(?=8|11|17)";


        //需求2  爬取版本号为8 11 17的java文本 需要加上后面的数字
        String regex2="((?i)java)(8|11|17)";
        //这种写法也可以还可以用占位的方法
        String regex21="((?i)java)(?:8|11|17)";


        //需求3 爬取除了 8  11  17

        String regex3="((?i)java)(?!8|11|17)";
        Pattern p = Pattern.compile(regex3);
        Matcher m = p.matcher(str);

        while(m.find()){
            System.out.println(m.group());
        }
        //s输出结果JaVa
        //Java
        //JAva
        //Java
        //(?i)忽略大小写


    }
}

在这里?相当于占位

贪婪爬取和非贪婪

贪婪爬取:爬取数据时尽可能多的爬取
贪婪爬取:爬取数据时尽可能少的爬取

String str ="Java自从95年问世以来,abbbbbbbbbbbbaaaaaaaaaaa"+"经历了很多版本,目前企业中用的最多的是JaVa8和Java11,"+
                "因为这两个是长期支持的版本,下一个长期支持的版本是JAva17,相信在未来不久Java17也会逐渐登上历史舞台";

ab+ 加表示一个或多个 那么可以是abbbbbbbbbbbb也可以是ab
那么贪婪爬取(java默认的爬取)则是abbbbbbbbbbbb
非贪婪ab
只写+和*表示贪婪匹配 +?和*?表示非贪婪

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

        while(m.find()){
            System.out.println(m.group());
        }
    }//打印结果abbbbbbbbbbbb

正则表达式在字符串方法中使用

在这里插入图片描述

 public static void main(String[] args) {

        //有一段字符串 小诗诗dadwdsdasda12312321小丹丹adafsge1234小惠惠
        //要求1 把字符串中三个名字之间的字母用vs替代
        //要求2 把字符串中的三个名字切割出去


        String regex="小诗诗dadwdsdasda12312321小丹丹adafsge1234小惠惠";
        //第一个传入需要代替文本的正则表达式dadwdsdasda
        //第二个传入需要替换成的字符  vs

        //底层原理他也会创见文本解析器对象  然后读取符合条件的字符 用第二个代替

        String result = regex.replaceAll("[\\w&&[^_]]+", "vs");
        System.out.println(result);//小诗诗vs小丹丹vs小惠惠


        //2要求2 把字符串中的三个名字切割出去

        //传入需要切割字符的正则表达式即可  返回值为数组
        String[] s = regex.split("[\\w&&[^_]]+");
        for (int i = 0; i < s.length; i++) {
            System.out.println(s[i]);
        }

分组

在这里插入图片描述

捕获分组

捕获分组就是把这一组的数据捕获出来,再用一次。

  • 需求1:判断一个字符串的开始字符和结束字符是否一致?只考虑一个字符
  • 举例:a123a、b456b、17891、&abc&
  • 需求2:判断一个字符串的开始部分和结束部分是否一致?可以有多个字符
  • 举例:abc123abc、b456b、123789123、&!@abc&!@
  • 需求3:判断一个字符串的开始部分和结束部分是否一致?开始部分内部每个字符也需要一致
  • 举例:aaa123aaa、bbb456bbb、111789111、&&abc&&
public static void main(String[] args) {

       /*  需求1:判断一个字符串的开始字符和结束字符是否一致?只考虑一个字符
                * 举例:a123a、b456b、17891、&abc&*/

       /* (.): 表示把首字符分成一组,可以出现1个任意字符
                .+: 表示任意字符至少出现1次
            \\1: 表示把第1组的内容再用1次*/

        //拿到一个字符串 可以把他拆成3分看  然后写正则表达式 a 123 a
        String regex="(.).+\\1";
        System.out.println("a123a".matches(regex));//true
        System.out.println("&abc&".matches(regex));//t
        System.out.println("a123b".matches(regex));//false



       /* * 需求2:判断一个字符串的开始部分和结束部分是否一致?可以有多个字符
                * 举例:abc123abc、b456b、123789123、&!@abc&!@*/
        String regex1="(.+).+\\1";
        //第一个(.+)表示 任意字符出现一次或者多次
        //第二个同上
        //\\1: 表示把第1组的内容再用1次   第一组就是第一个左括号的内容
        System.out.println("ab123ab".matches(regex1));//true
        System.out.println("&aabc&a".matches(regex1));//t
        System.out.println("aa123ab".matches(regex1));//false



        /*需求3:判断一个字符串的开始部分和结束部分是否一致?开始部分内部每个字符也需要一致
                * 举例:aaa123aaa、bbb456bbb、111789111、&&abc&&*/
        String regex2="((.)\\2*).+\\1";
        //(.)表示任意字符 加上\\2表示首字符拿出来再次使用
        ///*  表示把\\2重复0次或多次
        System.out.println("aaa123aaa".matches(regex2));//true
        System.out.println("111789111".matches(regex2));//t
        System.out.println("aab123abb".matches(regex2));//false


在正则表达式内部使用分组:\\组号
在正则表达式外部使用分组:$组号

练习

    public static void main(String[] args) {

        String str="我要学学编编编编程程程程程";
        //学学
         //编编编编
        //程程程程程

        //要做的是去点重复  用方法 replaceAll
        //写正则表达式
        //(.)表示任意字符出现0次或多次  \\1表示重复第一组 +表示出现1次或多次
        //第二个内容$1表示要替换的内容 为第一组第一个
        String s = str.replaceAll("(.)\\1+", "$1");
        System.out.println(s);
    }

非捕获分组

在这里插入图片描述

public static void main(String[] args) {
         /*
            非捕获分组:
                分组之后不需要再用本组数据,仅仅把数据括起来。

            身份证号码:
               41080119930228457x
               510801197609022309
               15040119810705387X
               430102197606046442
         */
        // 身份证号的简易正则表达式
        String IDRegex = "[1-9]\\d{16}(?:\\d|X|x)";
        //非捕获分组 不占用组好

总结

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1086089.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vscode利用lauch.json和docker中的delve调试本地crdb

---- vscode利用delve调试crdb 创建了一个delve容器用于debug crdbdelve&#xff1a; Delve是一个用于Go编程语言的调试器。它提供了一组命令和功能&#xff0c;可以帮助开发人员在调试过程中检查变量、设置断点、单步执行代码等操作。Delve可以与Go程序一起使用&#xff0c;…

自定义spring-boot-starter

自定义加载spring-boot-starter 第一步 创建一个Maven空项目 luban-spring-boot-starter 引入基础依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId><version>2.5.0</ve…

Linux下安装DM8

上传iso文件到服务器 文件路径放在 /works/tools/dm8_20230511_x86_rh6_64.iso mount镜像文件 执行mount命令 mkdir /mntdm8mount -t iso9660 /works/tools/dm8_20230511_x86_rh6_64.iso /mntdm8cd /mntdm8 创建数据库用户 groupadd dinstalluseradd -g dinstall -m -d …

测试面试官会做些什么?

虽然没有了金九银十&#xff0c;但是公司的测试HC&#xff08;headcount&#xff0c;指公司HR预计招聘的员工人数&#xff09;还是没有完全锁死&#xff0c;断断续续的也在帮着面试一些人。本文就以自己的经验&#xff0c;从面试官的角度&#xff0c;聊聊面试测试过程中的那些事…

【C/C++】STL——深度剖析list容器

​&#x1f47b;内容专栏&#xff1a; C/C编程 &#x1f428;本文概括&#xff1a;list的介绍与使用、深度剖析及模拟实现。 &#x1f43c;本文作者&#xff1a; 阿四啊 &#x1f438;发布时间&#xff1a;2023.10.12 一、list的介绍与使用 1.1 list的介绍 cpluplus网站中有关…

fastjson-BCEL不出网打法原理分析

FastJson反序列化漏洞 与原生的 Java 反序列化的区别在于&#xff0c;FastJson 反序列化并未使用 readObject 方法&#xff0c;而是由 FastJson 自定一套反序列化的过程。通过在反序列化的过程中自动调用类属性的 setter 方法和 getter 方法&#xff0c;将JSON 字符串还原成对…

低代码提速应用开发

低代码介绍 低代码平台是指一种能够帮助企业快速交付业务应用的平台。自2000年以来&#xff0c;低代码市场一直充斥着40大大小小的各种玩家&#xff0c;比如国外的Appian、K2、Pega Systems、Salesforce和Ultimus&#xff0c;国内的H3 BPM。 2015年以后&#xff0c;这个市场更是…

《3D 数学基础》几何检测-相交性检测

目录 1. 2D直线相交 2. 3D射线相交点 3. 射线和平面的交点 4. 3个平面的交点 5. 射线和圆或者球交点 6. 两个圆或者球是否相交 7. 球和平面的相交性检测 8. 射线和AABB的相交性&#xff08;13.17&#xff09; 9. 射线和三角形的相交性&#xff08;13.16&#xff09; …

visual studio设置主题和背景颜色

visual studio2019默认的主题有4种&#xff0c;分别是浅白色、深黑色、蓝色、蓝(额外对比度)&#xff0c;背景颜色默认是纯白色RGB(255,255,255)。字体纯白色看久了&#xff0c;眼睛会感到酸痛、疲劳&#xff0c;建议改成浅白RGB(250,250,250)、豆沙绿RGB(85,123,105)、透明蓝白…

为什么要用回馈式电子负载

回馈式电子负载主要作用是模拟真实负载情况下的电流和电压变化&#xff0c;它在电子设备的开发、测试和调试过程中起到重要的作用。回馈式电子负载可以模拟各种负载条件&#xff0c;包括不同的电流和电压变化&#xff0c;这对于测试和验证电子设备的性能非常重要&#xff0c;可…

ios UI 基础开发一

目录 第一节&#xff1a;基础库 第二节&#xff1a;弹出模拟器的键盘 第三节&#xff1a;模拟器回到桌面 第四节&#xff1a;Viewcontroller 与 View 的关系 第五节&#xff1a;快捷键 第六节&#xff1a;键盘召回 ​第七节&#xff1a;启动流程xcode介绍 第八节&#xf…

英国金融科技公司【kennek】完成1250万美元融资

来源&#xff1a;猛兽财经 作者&#xff1a;猛兽财经 猛兽财经获悉&#xff0c;总部位于英国伦敦的金融科技公司kennek今日宣布已完成1250万美元种子轮融资。 本轮融资由HV Capital领投&#xff0c;荷兰创始人基金、AlbionVC、FFVC、Plug Play Ventures和Syndicate One参与。 …

java Maven入门笔记

后端Web开发技术的学习&#xff0c;我们要先学习Java项目的构建工具&#xff1a;Maven 目录 Maven概述Maven介绍及其作用Maven模型介绍Maven仓库Maven安装 IDEA集成Maven配置Maven环境当前工程设置全局设置 Maven项目创建Maven项目POM配置详解Maven坐标详解 导入Maven项目 依赖…

脂质代谢+预后模型+WGCNA+单细胞多种要素分析

今天给同学们分享一篇脂质代谢预后模型WGCNA单细胞的生信文章“A Novel Lipid Metabolism and Endoplasmic Reticulum Stress-Related Risk Model for Predicting Immune Infiltration and Prognosis in Colorectal Cancer”&#xff0c;这篇文章于2023年9月8日发表在Int Mol S…

在服务器上解压.7z文件

1. 更新apt sudo apt-get update2. 安装p7zip sudo apt-get install p7zip-full3. 解压.7z文件 7za x WN18RR.7z

ETL数据转换方式有哪些

ETL数据转换方式有哪些 ETL&#xff08;Extract&#xff0c; Transform&#xff0c; Load&#xff09;是一种常用的数据处理方式&#xff0c;用于从源系统中提取数据&#xff0c;进行转换&#xff0c;并加载到目标系统中。 数据清洗&#xff08;Data Cleaning&#xff09;&am…

github 中关于Pyqt 的module view 操作练习

代码摘自&#xff0c;Pyside6 中的示例代码部分 # -*- coding: utf-8 -*- import sys from PySide6.QtWidgets import * from PySide6.QtGui import * from PySide6.QtCore import * from PySide6.QtSql import QSqlDatabase, QSqlQueryModel, QSqlQuery import os os.chdir(os…

C++学习——“面向对象编程”的涵义

以下内容源于C语言中文网的学习与整理&#xff0c;非原创&#xff0c;如有侵权请告知删除。 类是一个通用的概念&#xff0c;C、Java、C#、PHP 等很多编程语言中都支持类&#xff0c;都可以通过类创建对象。我们可以将类看做是结构体的升级版&#xff0c;C语言的晚辈们看到了C…

Linux网络编程:UDP协议和TCP协议

目录 一. 对于端口号的理解 1.1 网络通信五元组 1.2 端口号的划分策略 二. 网络通信中常用的指令 2.1 netstat指令 2.2 pidof指令 三. udp协议 3.1 udp的概念及特点 3.2 udp协议端格式 3.3 对于面向数据报及应用层发送与读取数据的理解 四. tcp协议的概念及特点 五.…

智能指针简介

智能指针简介 文章目录 智能指针简介摘要什么是智能指针C 98 中的智能指针C 11 中的智能指针C 17 中的智能指针智能指针常用函数 关键字&#xff1a; 智能指针、 auto_ptr、 std::shared_ptr、 std::unique_ptr、 std::weak_ptr 摘要 之前基本都是学习的Qt版本的C&#x…