JAVA进阶学习05

一、正则表达式

1.1正则表达式简介

正则表达式其实是由一些特殊的符号组成的,它代表的是某种规则。

正则表达式的作用1:用来校验字符串数据是否合法
正则表达式的作用2:可以从一段文本中查找满足要求的内容

//按往常的方式来匹配字符串
//核心思想:先判断是否为异常数据,再返回true
public static boolean checkQQ(String qq){
        // 1、判断qq号码是否为null,是否用0开头,长度在6到20
        if(qq == null || qq.startsWith("0") || qq.length() < 6 || qq.length() > 20){
            return false;
        }

        // 2、判断qq号码中是否都是数字。
        for (int i = 0; i < qq.length(); i++) {
            // 根据索引提取当前位置处的字符。
            char ch = qq.charAt(i);
            // 判断ch记住的字符,如果不是数字,qq号码不合法。
            if(ch < '0' || ch > '9'){
                return false;
            }
        }
        // 3、说明qq号码肯定是合法
        return true;
    }


正则表达式的书写格式:
字符串.matches(正则表达式)

//用正则表达式匹配上述QQ字符串
//返回值是一个布尔类型
public static boolean checkQQ1(String qq){
    return qq != null && qq.matches("[1-9]\\d{5,19}");
}

1.2 正则表达式的书写规则

关于正则表达式的书写规则可以在API文档中进行查看,以下罗列部分规则:
请添加图片描述
代码演示如下:

/**
 * 正则表达式的匹配是从左到右逐个匹配
 */
public class RegexTest2 {
    public static void main(String[] args) {
        // 1、字符类(只能匹配单个字符)
        //[abc]
        System.out.println("a".matches("[abc]"));    // [abc]只能匹配a、b、c
        System.out.println("e".matches("[abcd]")); // false
        System.out.println("ab".matches("[abc]")); // false 
        //此时只匹配了ab中的a,b并没有匹配,修改方式如下
        System.out.println("ab".matches("[abc][abc]")); // true 即每个括号匹配一个字符
		
		//[^abc]
        System.out.println("d".matches("[^abc]"));   // true [^abc] 不能是abc
        System.out.println("a".matches("[^abc]"));  // false

		//[[a-zA-Z]]
        System.out.println("b".matches("[a-zA-Z]")); // [a-zA-Z] 只能是a-z A-Z的字符
        System.out.println("2".matches("[a-zA-Z]")); // false
		System.out.println("2".matches("[0-9]")); // true
		System.out.println("ab".matches("[a-zA-Z0-9]")); // false  同理无法匹配多字符
		
		//[a-d[m-p]] 或符号
		System.out.println("2".matches("[a-d[m-p]]")); // 若字符在(a-d)或(m-p)之间返回true

		//[a-z&&[^bc]] 且符号
        System.out.println("k".matches("[a-z&&[^bc]]")); // : a到z,除了b和c
        System.out.println("b".matches("[a-z&&[^bc]]")); // false
        System.out.println("&".matches("[a-z&[^bc]]")); // true 仅仅写一个&符号就是匹配它

       
        //注意:以上带 [内容] 的规则都只能用于匹配单个字符

        // 2、预定义字符(只能匹配单个字符)  .  \d  \D   \s  \S  \w  \W
        System.out.println("你".matches(".")); // .可以匹配任意字符
        System.out.println("你好".matches(".")); // false

        // \转义
        //System.out.println("""); 此时代码将会报错
        System.out.println("\""); //转义后可以用来匹配双引号
       
        // 其他特殊字符的匹配
        System.out.println("3".matches("\\d"));  // \d: 0-9用来匹配数字
        System.out.println("a".matches("\\d"));  //false

        System.out.println(" ".matches("\\s"));   // \s: 小写,代表一个空白字符
        System.out.println("a".matches("\s")); // false

        System.out.println("a".matches("\\S"));  // \S: 大写,代表一个非空白字符
        System.out.println(" ".matches("\\S")); // false

		// \w: 小写w等价于[a-zA-Z_0-9] 
		//单个字母、数字、下划线匹配
        System.out.println("a".matches("\\w")); 
        System.out.println("_".matches("\\w")); // true
        System.out.println("徐".matches("\\w")); // false
		
		// 大写W等价于:[^\w]不能是a-zA-Z_0-9
        System.out.println("徐".matches("\\W"));  
        System.out.println("a".matches("\\W"));  // false
		System.out.println("23232".matches("\\d")); // false 注意:以上预定义字符都只能匹配“单个”字符。

        // 3、数量词: ?   *   +   {n}   {n, }  {n, m}
        //用来修饰被匹配的字符
        //?
        System.out.println("a".matches("\\w?"));   // ? 代表0次或1次
        System.out.println("".matches("\\w?"));    // true
        System.out.println("abc".matches("\\w?")); // false

		//*
        System.out.println("abc12".matches("\\w*"));   // * 代表0次或多次
        System.out.println("".matches("\\w*"));        // true
        System.out.println("abc12张".matches("\\w*")); // false

		//+
        System.out.println("abc12".matches("\\w+"));   // + 代表1次或多次
        System.out.println("".matches("\\w+"));       // false
        System.out.println("abc12张".matches("\\w+")); // false

		//{}
        System.out.println("a3c".matches("\\w{3}"));   // {3} 代表要正好是n次
        System.out.println("abcd".matches("\\w{3}"));  // false
        System.out.println("abcd".matches("\\w{3,}"));     // {3,} 代表是>=3次
        System.out.println("ab".matches("\\w{3,}"));     // false
        System.out.println("abcde徐".matches("\\w{3,}"));     // false
        System.out.println("abc232d".matches("\\w{3,9}"));     // {3, 9} 代表是  大于等于3次,小于等于9次

        // 4、其他几个常用的符号:(?i)忽略大小写 、 或:| 、  分组:()
        System.out.println("abc".matches("(?i)abc")); // true
        System.out.println("ABC".matches("(?i)abc")); // true
        System.out.println("aBc".matches("a((?i)b)c")); // true
        System.out.println("ABc".matches("a((?i)b)c")); // false

        // 需求1:要求要么是3个小写字母,要么是3个数字。
        System.out.println("abc".matches("[a-z]{3}|\\d{3}")); // true
        System.out.println("ABC".matches("[a-z]{3}|\\d{3}")); // false
        System.out.println("123".matches("[a-z]{3}|\\d{3}")); // true
        System.out.println("A12".matches("[a-z]{3}|\\d{3}")); // false

        // 需求2:必须是”我爱“开头,中间可以是至少一个”编程“,最后至少是1个”666“
        System.out.println("我爱编程编程666666".matches("我爱(编程)+(666)+"));
        System.out.println("我爱编程编程66666".matches("我爱(编程)+(666)+"));
    }
}

1.3 正则表达式的使用案例

/**
 * 校验用户输入的电话是否合法
 */
public class RegexTest3 {
    public static void main(String[] args) {
        checkPhone();
    }

    public static void checkPhone(){
        while (true) {
            System.out.println("请您输入您的电话号码(手机|座机): ");
            Scanner sc = new Scanner(System.in);
            String phone = sc.nextLine();
            // 18676769999  010-3424242424 0104644535
            if(phone.matches("(1[3-9]\\d{9})|(0\\d{2,7}-?[1-9]\\d{4,19})")){
                System.out.println("您输入的号码格式正确~~~");
                break;
            }else {
                System.out.println("您输入的号码格式不正确~~~");
            }
        }
    }
}

1.4 正则插件介绍

可以在插件商场里搜索any-rule,内置多种正则表达式
在这里插入图片描述
在使用时,在matches函数中直接右键插入正则表达式

二、信息爬取的基本应用

2.1信息爬取简介

通过对正则表达式的学习,了解了正则表达式的作用之一,用来校验数据格式的正确性。
接下就是正则表达式的第二个作用:在一段文本中查找满足要求的内容

长段信息匹配的基础类

正则表达式对象:Pattern
文本解析器对象:Matcher

public class Test {
    public static void main(String[] args) {
        
        String str="12354654654";
        String regex="//d{3}";

        //获取正则表达式的对象
        Pattern p=Pattern.compile(regex);
        
        //运用表达式对象来匹配文本
        Matcher m=p.matcher(str);
        //用对象m在字符串str中寻找满足正则表达式对象p的文本串
        
        //利用循环来打印匹配成功的子串
        //find函数可以将返回是否找到子串,find会不断向后寻找符合条件的子串
        while(m.find()){
            //group函数利用find函数找到的字符串下标来截取子串
            String ss = m.group();
            System.out.println(ss);
            
        }
    }
}

2.2 有条件的信息爬取

当我们匹配到符合子串时,并不需要全部内容作为输出,例如匹配到java8时要去掉其版本号

public class Test2 {
    public static void main(String[] args) {
        String regex="((?i)java)(?=8|11|17)";
        //可以匹配java8或jav11或java17,但最终省去后面的版本号,只保留前面
        //(?i)表示忽略大小写,对当前括号内的内容做制约
        //(?=8|11|17)该括号表示对前面的括号做补充 ?是占位符 =表示占位符可能取的值
        //8|11|17表示三种数字都可以
 

        String regex1="((?i)java)(?:8|11|17)";
        //匹配到对应的后,获取的字符串带版本号

        String regex2="((?i)java)(?!8|11|17)";
        //爬取除了版本号为8,11,17的所有java文本
    }
}

2.3贪婪爬取和非贪婪爬取

贪婪爬取:在爬取过程中,尽可能地多获取数据
非贪婪爬取:在爬取过程中,尽可能地少获取数据

 public static void main(String[] args) {
        //贪婪爬取

        String str="abbbbbb";
        String regex="ab+"; //贪婪爬取结果abbbbbb
        String regex1="ab+?"; //非贪婪爬取结果ab
        
        Pattern compile = Pattern.compile(regex);
        Matcher m =compile.matcher(str);
        while (m.find()){
            String group = m.group();
            System.out.println(group);
        }
    }

2.4 正则表达式的常用方法

正则表达式中常用的有替换(replace)和切割(split)两种方法

public static void main(String[] args) {
        String s ="j小yfdsdc小vuyfvki小yasgdlfiu";

        String regex="小";

        //1.将字符串中的小字替换成66
        //String replace1 = s.replace(regex,"66");
        //replace无法识别正则表达式,可用replaceAll
        String replace1 = s.replaceAll(regex,"66");
        System.out.println(replace1);

        //2.对字符串进行切割,并返回切割后的字符串数组
        String[] split = s.split(regex);
        for (int i = 0; i < split.length; i++) {
            System.out.println(split[i]);
        }
    }

三、正则表达式的分组

3.1 为什么要分组

分组的使用场景:当正则匹配时的子串可能出现多种情况(如 身份证的最后一位)或者某一部分可多次重复时(如 网址.com.cn)

注意

分组是有组号的,组号从1开始。以左括号为基准,最左侧的左括号内的是第一组。

3.2 捕获分组的用途

1.捕获分组用于正则内部\\

public static void main(String[] args) {
        //1.判断一个串的起始和结束字符是否一致
        String regex="(.).+\\1";
        //其中()是分组,内部的.是任意一个字符  .+表示可重复多个任意字符
        // \\1表示重复分组1,且当前匹配的字符应与分组1相等
        System.out.println("aba".matches(regex));//true
        System.out.println("1asd1".matches(regex));//true
        System.out.println(".5644.".matches(regex));//true
        System.out.println("------------------------------");

        //2.判断一个串的开始和结束字符“串”是否一致
        String regex1="(.+).+\\1";//判断串只用在组中用+
        System.out.println("ab6546ab".matches(regex1));//true
        System.out.println("123465461234".matches(regex1));//true
        System.out.println("???!asfd???!".matches(regex1));//true
        System.out.println("------------------------------");

        //3.判断一个字符串的开始和结束是否一致,且内部都是同一个字符
        String regex2="((.)\\2*).+\\1"; //(.)\2*表示将该内容重复多遍
        //(.)\\2*表示括号内的该组是第二组,*表示可以将该组内的值重复多遍
        System.out.println("aaa351aaa".matches(regex2));
        System.out.println("aaa351aa".matches(regex2));
    }
  1. 捕获分组用于正则外部$
public static void main(String[] args) {
        
        /*将我要学学学编编编编编编程程程程程程程
         *替换为
         * 我要学编程
         */
        
        String str = "我要学学学编编编编编编程程程程程程程";
        String s = str.replaceAll("(.)\\1+", "$1");
        //其中(.):表示重复内容的第一个字符
        //\\1+表示分组1可能会多次出现
        //后部的$1表示在正则表达式的外部调用分组1
        System.out.println(s);
    }

3.3 非捕获分组

非捕获分组分组后不占用组号,仅仅是用括号括起来

符号含义
(? : 正则表达式)获取所有内容
(? = 正则表达式)仅在匹配时使用,获取时只是括号前内容
(? ! 正则表达式)获取不是指定内容的前段

非捕获分组最常用的是第一种表达形式,一般用于阅读别人写的正则表达式,自己不常用

Java进阶学习路线通常包括以下几个阶段: 1. **基础知识**: - 学习基础语法:变量、数据类型、运算符、流程控制(如条件、循环)、数组、集合等。 - 熟悉面向对象编程(OOP)概念:类、对象、封装、继承、多态。 2. **中级技能**: - 掌握设计模式:单例、工厂、观察者、策略等,理解如何优化软件架构。 - 异常处理和IO流:异常处理机制,文件操作、网络通信等。 - 数据结构和算法:了解常用的数据结构(如栈、队列、链表、树、图),并能用Java实现基本算法。 3. **框架应用**: - Spring框架:深入学习Spring MVC和Spring Boot,理解依赖注入、AOP等高级特性。 - Hibernate或MyBatis:数据库访问层技术,ORM工具的学习和实践。 - 学习Java多线程和并发工具库(如synchronized、ExecutorService、Future、CompletableFuture)。 - 分布式系统原理:学习RPC(如RMI、Hessian、Thrift)和消息中间件(如JMS、RabbitMQ)。 5. **性能优化**: - 内存管理:垃圾回收机制,内存泄漏检测。 - 性能分析:使用JProfiler、VisualVM等工具进行性能监控和调优。 6. **实战项目**: - 实施一个大型企业级项目,涉及数据库设计、用户界面、业务逻辑等多个模块。 7. **持续学习**: - 阅读源码,如开源框架源码,提升编程能力。 - 关注新技术趋势,例如微服务、云计算、大数据处理等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值