常用API-正则表达式、爬虫、分组

1.正则表达式

正则表达式可以校验字符串是否满足一定的规则,并用来校验数据格式的合法性

初体验正则表达式

public class RegexDemo1 {
    public static void main(String[] args) {
        /*校验qq是否正确
        * 规则:6~15位之间,不能0开头,必须全是数字*/
        String qq = "2426580778";

        boolean result = checkQQ(qq);
        System.out.println(result);

        //正则表达式
        System.out.println(qq.matches("[1-9]\\d{5,14}"));
    }

    //核心思想:先把异常数据进行过滤,剩下的就是满足要求的数据
    public static boolean checkQQ(String qq){
        //6~15位之间
        int len = qq.length();
        if(len > 15 || len < 6){
            return false;
        }
        //不能0开头
        char ch = qq.charAt(0);
        if(ch == '0'){
            return false;
        }
        //都是数字
        for (int i = 0; i < qq.length(); i++) {
            char c = qq.charAt(i);
            if(c < '0' || c > '9'){
                return false;
            }
        }
        return true;
    }
}

正则表达式的作用:

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

正则表达式规则:

字符类(只匹配一个字符)
[abc]只能是a,或b,或c
[^abc]

除了a,b,c之外的任何字符

[a-zA-Z]

a到zA到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的交集。(等同于[a-lq-z])
预定义字符(只能匹配一个字符)
.任何字符
\d一个数字:[0-9]
\D非数字:[^0-9]
\s一个空白字符:[\t\n\x0B\f\r]
\S非空白字符:[^\s]
\w[a-zA-Z_0-9]大小写英文、数字、下划线
\W[^\w]一个非单词字符
public static void main(String[] args) {
        // \ 表示转义字符 改变后面那个字符原本含义

        // " 在Java中表示字符串的开头或结尾
        // 此时\表示转义字符,改变后面那个双引号原本含义
        //所以才能以字符串的形式打印一个双引号
        System.out.println("\"");

        // \表示转义字符
        // \\前面那个\是一个转移字符,改变了后面那个\原本含义,把它变成一个普普通通的\而已
        System.out.println("D:\\JavaProjects\\allProject\\myapi\\src\\demo7\\RegexDemo2.java");

        // \\d表示任意的一个数字
        //两个\表示一个\,前面的\对后面的\进行转义,把后面的\变成一个普普通通的\
        System.out.println("3".matches("\\d"));//true
}
数量词
X?X,一次或0次
X*X,零次或多次
X+X,一次或多次
X{n}X,正好n次
X{n,}X,至少n次
X{n,m}X,至少n但不超过m次

正则表达式可以使用插件"AnyRule"快速生成

 正则表达式小结

符号含义举例
[ ]里面的内容出现一次[0-9] [a-zA-Z]
()分组a(bc)+
^取反[^abc]
&&交集,不能写单个的&[a-z&&m-p]
|写在方括号外表示并集[a-zA-z0-9] X|x
.任意字符\n回车符号不匹配
\转义字符\\d
\\d0-9\\d+
\\D非0-9\\D+
\\s空白字符[\t\n\x0B\f\r]
\\S非空白字符[^\s]
\\w单词字符[a-zA-Z_0-9]
\\W非单词字符[^\w]
?0次或1次\\d?
*0次或多次\\d*  (abc)*
+1次或多次\\d+  (abc)+
{}具体次数a{7}  \\d{7,19}
(?!)忽略后面字符的大小写(?!)abc
a((?!)b)c只忽略b的大小写a((?!)b)c

2.爬虫

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

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

public class RegexDemo1 {
    public static void main(String[] args) {
        /*有如下文本,按要求爬取
        * Java自从问世以来,经历了很多版本,目前企业中使用最多的是Java8和Java11,
        * 因为这两个是长期支持版本,下一个长期支持版本是Java17,相信不久将来Java17也会登上历史舞台
        * 要求:找出所有的JavaXX*/

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

        //Pattern:表示正则表达式
        //Matcher:文本匹配器,按照正则表达式的规则去读取字符串,从头开始读取

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

        //拿着文本匹配器从头开始读取,寻找是否有满足规则的子串
        //如果没有,方法返回false
        //如果有,方法返回true,并记录符合要求的子串的索引
        while(m.find()){
            //方法底层会根据find方法记录的索引进行字符串的截取并返回
            String s = m.group();
            System.out.println(s);
        }

    }
}

贪婪爬取和非贪婪爬取

贪婪爬取:在爬取数据的时候尽可能多的获取数据

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

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

只写+或*表示贪婪爬取   +?或*?表示非贪婪爬取

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

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

        String str = "Java自从问世以来,经历了很多版本,abbbbbbbbbb";
        //贪婪爬取
        String regex = "ab+";

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

        //非贪婪爬取
        String regex1 = "ab+?";

        Pattern p1 = Pattern.compile(regex1);
        Matcher m1 = p1.matcher(str);
        while (m1.find()){
            System.out.println(m1.group());//ab
        }
    }
}

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

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

3.分组

分组就是一个小括号

正则表达式的分组有两种:

捕获分组、非捕获分组

捕获分组:

可以获取每组中内容反复使用

捕获分组规则:

每组的组号就是序号

从1开始,连续不间断

以左括号为基准,最左边的是第一组,其次是第二组,以此类推

public static void main(String[] args) {
        //举例:a123a  !123!  &abc&  a123b

        // \\1:表示把第1组的内容再拿出来用一次
        String regex = "(.).+\\1";
        System.out.println("a123a".matches(regex));//true
        System.out.println("!123!".matches(regex));//true
        System.out.println("&abc&".matches(regex));//true
        System.out.println("a123b".matches(regex));//false
        System.out.println("------------------------");

        //举例:abc123abc  c123c  12345123  @!123@!  123ac23

        String regex1 = "(.+).+\\1";
        System.out.println("abc123abc".matches(regex1));//true
        System.out.println("c123c".matches(regex1));//true
        System.out.println("12345123".matches(regex1));//true
        System.out.println("@!123@!".matches(regex1));//true
        System.out.println("123ac23".matches(regex1));//false
        System.out.println("--------------------------------");

        //举例:aaa123aaa  !!!abc!!!  1112351111  @@!ab@@  &&123&!

        //(.)把首字母看成一组
        // \\2把首字母拿出来再次使用
        // *:作用于\\2,表示后面重复的内容出现0次或多次
        String regex2 = "((.)\\2*).+\\1";
        System.out.println("aaa123aaa".matches(regex2));//true
        System.out.println("!!!abc!!!".matches(regex2));//true
        System.out.println("1112351111".matches(regex2));//true
        System.out.println("@@!ab@@".matches(regex2));//true
        System.out.println("&&123&!".matches(regex2));//false
}

后续还要继续使用本组的数据。

正则表达式内部使用:\\组号

正则表达式外部使用:$组号

public static void main(String[] args) {
        String s = "我要吃吃吃吃吃吃吃吃好好好好好好吃的";
        String str = s.replaceAll("(.)\\1+", "$1");
        System.out.println(str);//我要吃好吃的
}

非捕获分组:

分组之后不需要再用本组数据,仅仅是把数据括起来,不占用组号

符号含义举例
(?:正则)获取所有Java(?:8|11|17)
(?=正则)获取前面部分Java(?=8|11|17)
(?!正则)获取不是指定内容的前面部分Java(?!8|11|17)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值