学习java时候的笔记(十九)

发布于:2024-04-20 ⋅ 阅读:(19) ⋅ 点赞:(0)

正则表达式

作用:

  • 校验字符串是否满足规则
  • 在一段文本中查找满足要求的内容

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

说明
[abc] 只能是a,b或c
[^abc] 除了a,b,c之外的任何字符
[a-zA-Z] a 到 z, A 到 Z(范围)
[a-d[m-p]] a 到 d, 或 m 到 p
[a - z && [def]] a 到 z和def的交集。为: d, e, f
[a - z && [^bc]] a 到 z和非bc的交际 ( 等同于[ad-z] )
[a-z&&[^m-p]] a 到 z和除了m到p的交集

Demo:

public class RegexDemo1 {
    public static void main(String[] args) {

        System.out.println("-------------1----------------");
        String str1 = "a";
        System.out.println(str1.matches("[abc]"));//true
        System.out.println(str1.matches("[a-c]"));//true
        System.out.println(str1.matches("[^a-c]"));//true
        System.out.println("ab".matches("[a-c]"));//false 原因: [a-c]只能匹配一个,有两个字符要去匹配两次
        System.out.println("ab".matches("[a-c][a-c]"));//true

        System.out.println("-------------2----------------");
        System.out.println("n".matches("[a-d[m-p]]"));//true
        System.out.println("nn".matches("[a-d[m-p]]"));//false
        System.out.println("nn".matches("[a-d[m-p]][a-d[m-p]]"));//true

        System.out.println("-------------3----------------");
        //如果要表示两个范围的交集, 要用 &&
        //如果只写一个 & ,则仅仅是表示一个字符 &
        System.out.println("a".matches("[a-z&&[def]]"));//false
        System.out.println("d".matches("[a-z&&[def]]"));//true
        System.out.println("a".matches("[a-z&[def]]"));//true

        System.out.println("-------------4----------------");
        System.out.println("a".matches("[a-z&&[^def]]"));//true
        System.out.println("d".matches("[a-z&&[^def]]"));//false



    }
}

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

表达式 字符
. 任何字符
\d 一个数字: [0-9]
\D 非数字: [^0-9]
\s 一个空白字符: [\t\n\x0B\f\r]
\S 非空白字符: [^\s]
\w [a-zA-Z_0-9]英文、数字、下划线
\W [^\w]一个非单词字符

Demo:

public class RegexDemo2 {
    public static void main(String[] args) {
        System.out.println("-------------1----------------");
        //.表示一个任意字符
        System.out.println("你".matches("."));//true
        System.out.println("你n".matches("."));//false
        System.out.println("你n".matches(".."));//true

        System.out.println("-------------2----------------");
        //  \d表示一个数字
        System.out.println("9".matches("\\d"));//true
        System.out.println("a".matches("\\d"));//false
        System.out.println("99".matches("\\d"));//false
        System.out.println("99".matches("\\d\\d"));//true

        System.out.println("-------------3----------------");
        // \D 表示非数字
        System.out.println("9".matches("\\D"));//false
        System.out.println("a".matches("\\D"));//true
        System.out.println("ab".matches("\\D"));//false
        System.out.println("ab".matches("\\D\\D"));//true

        System.out.println("-------------3----------------");
        // \s一个空白字符
        System.out.println("\t".matches("\\s"));//true
        System.out.println("\t\t".matches("\\s"));//false
        System.out.println(" ".matches("\\s"));//true
        System.out.println("  ".matches("\\s"));//false

        System.out.println("9".matches("\\s"));//false
        System.out.println("a".matches("\\s"));//false

        System.out.println("-------------4----------------");
        // \S非空白字符
        System.out.println("\t".matches("\\S"));//false
        System.out.println(" ".matches("\\S"));//false
        System.out.println("a".matches("\\S"));//true
        System.out.println("9".matches("\\S"));//true

        System.out.println("-------------5----------------");
        // \w [a-zA-Z_0-9]英文、数字、下划线
        System.out.println("a".matches("\\w"));//true
        System.out.println("A".matches("\\w"));//true
        System.out.println("0".matches("\\w"));//true
        System.out.println("_".matches("\\w"));//true

        System.out.println("-------------5----------------");
        // \W 一个非单词字符
        System.out.println("&".matches("\\W")); //true
        System.out.println("a".matches("\\W")); //false
        System.out.println("A".matches("\\W")); //false
        System.out.println("0".matches("\\W")); //false
        System.out.println("_".matches("\\W")); //false
    }
}

数量词(表中的 ‘X’ 代表任意内容)

表达式 说明
X? X,一次或0次
X* X,零次或多次
X+ X,一次或多次
X{n} X,正好n次
X{n, } X,至少n次
X{n, m} X,至少n次但不超过m次

Demo:

public class RegexDemo3 {
    public static void main(String[] args) {
        System.out.println("a".matches("[abc]?"));//true  一次或0次
        System.out.println("".matches("[abc]?"));//true

        System.out.println("aaa".matches("[abc]*"));//true  零次或多次
        System.out.println("".matches("[abc]*"));//true

        System.out.println("".matches("[abc]+"));//false  一次或多次
        System.out.println("a".matches("[abc]+"));//true
        System.out.println("aa".matches("[abc]+"));//true

        System.out.println("aaa".matches("[abc]{3}"));//true  刚好三次
        System.out.println("aaaa".matches("[abc]{3}"));//false
        System.out.println("aa".matches("[abc]{3}"));//false

        System.out.println("aa".matches("[abc]{3,}"));//false  至少三次
        System.out.println("aaa".matches("[abc]{3,}"));//true
        System.out.println("aaaa".matches("[abc]{3,}"));//true

        System.out.println("aaa".matches("[abc]{3,4}"));//true//至少三次但不超过四次
        System.out.println("aaaa".matches("[abc]{3,4}"));//true
        System.out.println("aa".matches("[abc]{3,4}"));//false
        System.out.println("aaaaa".matches("[abc]{3,4}"));//false


    }
}

爬虫

正则表达式的对象:Pattern

文本匹配器对象:Matcher

Pattern常见方法:

(待完善)

Matcher常见方法:

(待完善)

方法名 说明
find() 拿着文本匹配器从头开始读取, 寻找是否有满足规则的字符串.如果没有,方法返回false,如果有,返回true
m.group() 该方法底层会根据find方法记录的索引进行字符串的截取,会把截取的小字符串进行返回

Demo1:

package RegexDemo;

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

public class crawler {
    public static void main(String[] args) {
        /*有如下文本,请按照要求爬取数据。
        Java自从95年问世以来,经历了很多版本,目前企业中用的最多的是ava8和ava11,
        因为这两个是长期支持版本,下一个长期支持版本是Java17,相信在未来不久Java17也会逐渐登上历史舞台
        要求:找出里面所有的JavaXX
        */
        String str = "Java自从95年问世以来,经历了很多版本,目前企业中用的最多的是Java8和Java11," +
                "因为这两个是长期支持版本,下一个长期支持版本是Java17,相信在未来不久Java17也会逐渐登上历史舞台";


//        method1(str);

        //1.获取正则表达式的对象,也就是Pattern的对象
        Pattern p = Pattern.compile("Java\\d{0,2}");
        //2.获取文本匹配器的对象
        Matcher m = p.matcher(str);
        //3.利用循环
        while (m.find()){
            String s = m.group();
            System.out.println(s);
        }



    }

    private static void method1(String str) {
        //Pattern: 表示正则表达式
        //Matcher: 文本匹配器,作用按照正则表达式的规则去读取字符串,从头开始读取。在大串中去找符合匹配规则的子串。


        //1.获取正则表达式的对象,也就是Pattern的对象
        Pattern p = Pattern.compile("Java\\d{0,2}");
        //2.获取文本匹配器的对象
        //m: 文本匹配器的对象
        //str: 大的字符串
        //p: 规则
        //m要在str中找符号p规则的小的字符串
        Matcher m = p.matcher(str);

        //拿着文本匹配器从头开始读取, 寻找是否有满足规则的字符串
        //如果没有,方法返回false
        //如果有,返回true,在底层记录子串的起始索引和结束索引+1
        boolean b = m.find();

        //该方法底层会根据find方法记录的索引进行字符串的截取
        //会把截取的小字符串进行返回
        String s1 = m.group();
        System.out.println(s1);
    }
}

Demo2:

package RegexDemo;

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

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

        //定义正则表达式
        //? 理解为前面的数据Java
        //= 表示后面要跟随的数据
        //但是在获取的时候只获取前半部分
        // (?i) : 忽略大小写
        String regex1 = "((?i)Java)(?=8|11|17)";

        //下面两个效果相同
        //使用 " : " 时获取数据的时候获取全部
        String regex2 = "((?i)Java)(8|11|17)";
        String regex3 = "((?i)Java)(?:8|11|17)";

        //去掉Java后面后 8/11/17 的数据
        String regex4 = "((?i)Java)(?!8|11|17)";

        Pattern p = Pattern.compile(regex1);
        Matcher m = p.matcher(s);
        while (m.find()) {
            System.out.print(m.group() + " ");
        }
        System.out.println();
        Pattern p1 = Pattern.compile(regex2);
        Matcher m1 = p1.matcher(s);
        while (m1.find()) {
            System.out.print(m1.group() + " ");
        }
        System.out.println();
        Pattern p2 = Pattern.compile(regex3);
        Matcher m3 = p2.matcher(s);
        while (m3.find()) {
            System.out.print(m3.group() + " ");
        }
        System.out.println();
        Pattern p3 = Pattern.compile(regex4);
        Matcher m4 = p3.matcher(s);
        while (m4.find()) {
            System.out.print(m4.group() + " ");
        }

    }
}

Demo3:

package RegexDemo;

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

public class crawlerThree {
    public static void main(String[] args) {
        /*需求1∶按照ab+的方式爬取ab,b尽可能多获取
        需求2:按照ab+的方式爬取ab,b尽可能少获取
         */
        String s ="Java自从95年问世以来,abbbbbbbbbbbbaaaaaaaaaaaaaaaaaa" +
                "经历了很多版本,目前企业中用的最多的是Java8和Java11,因为这两个是长期支持版本,下一个长期支持版本是Java17,相信在未来不久Java17也会逐渐登上历史舞台";


        //贪婪爬取  (Java默认)
        String regex = "ab+";

        Pattern p = Pattern.compile(regex);
        Matcher m = p.matcher(s);
        while (m.find()){
            System.out.println(m.group());
        }

        //非贪婪爬取  (在 " + " 后面加一个问号就行了)
        String regex1 = "ab+?";
        Pattern p2 = Pattern.compile(regex1);
        Matcher m2 = p2.matcher(s);
        while (m2.find()){
            System.out.println(m2.group());
        }
    }
}

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

方法名 说明
matches(String regex) 判断字符串是否满足正则表达式规则
replaceAll(String regex, String newstr) 按照正则表达式规则进行替换
split(String regex) 按照正则表达式的规则切割字符串

Demo4:

package RegexDemo;

public class crawlerFour {
    public static void main(String[] args) {
        /*有一段字符串:小诗诗dqwefqwfqwfwq12312小丹丹dqwefqwfqwfwq12312小惠惠
        要求1:把字符串中三个姓名之间的字母替换为vs
        要求2:把字符串中的三个姓名切割出来
         */

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

        String[] s1 = s.split("[\\w &&[^_]]+");
        for (int i = 0; i < s1.length; i++) {
            System.out.println(s1[i]);
        }
    }
}

最后:欢迎大家关注我的公众号
在这里插入图片描述


网站公告

今日签到

点亮在社区的每一天
去签到