第26讲 正则表达式详解

本文详细介绍了正则表达式的基本概念,包括字符类、预定义字符和数量词,以及在Java中的应用。同时,讲解了捕获分组的概念,包括分组、捕获和非捕获分组。此外,还讨论了爬虫的基础知识,包括如何在字符串中使用正则表达式进行匹配和数据提取,并提到了贪婪和非贪婪爬取的区别。
摘要由CSDN通过智能技术生成

API

API即应用程序编程接口,英文全称Application Programming Interface。

API是一些预先定义的函数,目的是提供应用程序与开发人员基于某软件或硬件得以访问一组例程的能力,而又无需访问源码,或理解内部工作机制的细节。

正则表达式是API的一种。

1 正则表达式

1.1 正则表达式简述

正则表达式定义了字符串的模式。正则表达式并不仅限于Java语言,但是在每种语言中有细微的差别。

定义在类 Pattern

正则表达式作用

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

技巧: 根据正确的数据,从左到右依次给出正则表达式。

1.2 字符类

只匹配一个字符

字符类含义
[abc]只能是abc
[^abc]除了abc外的所有字符
[a-zA-Z][a, z] 并 [A, Z]
[a-d[m-p]][a, d] 并 [m, p]
[a-z&&[bc]][a, z] 交 字符’b’‘c’
[a-z&&[ ^bc ]][a, z] 交 非字符’b’‘c’。等同于[ad-z]
[a-z&&[ ^m-p ]][a, z] 交 非[m, p]。等同于[a-lq-z]
(ab|c|[d-i])‘a’‘b’ 并 ‘c’ 并 [d, i]

1.3 预定义字符

只匹配一个字符

预定义字符含义
.任何字符,除了’\n’
\d数字字符匹配。等效于 [0-9]。
\D非数字字符匹配。等效于 [ ^0-9 ]。
\s匹配任何空白字符,包括空格、制表符、换页符等。与 [ \f\n\r\t\v ] 等效。
\S匹配任何非空白字符。与 [ ^ \f\n\r\t\v ] 等效。
\w匹配任何字类字符,包括下划线。与"[ A-Za-z0-9_ ]"等效。
\W与任何非单词字符匹配。与"[ ^A-Za-z0-9_ ]"等效。
[]里面的内容只出现一次
()分组。表示()里的内容是一个整体。
|写在[]外表示并集。方括号里什么都不写就是并集
&&交集。一个&表示字符’&’

\ 转义字符:用来改变其后紧跟的一个字符的含义。

在其他语言中,\\ 表示:我要在正则表达式中插入一个普通的反斜杠,不要给它任何特殊的意义。

在Java中,\\ 表示:我要插入一个正则表达式的反斜线,所以其后紧跟的一个字符具有特殊的意义。

即在 Java 的正则表达式中,两个\\代表其他语言中的一个\,这也就是为什么表示一位数字的正则表达式是\\d,而表示一个普通的反斜杠是\\

1.4 数量词

可以匹配多个字符

数量词含义
X?字符X出现0次或1次
X*字符X出现0次或多次
X+字符X出现1次或多次
X{n}字符X恰好出现n次
X{n,}字符X至少出现n次
X{n, m}字符X最少出现n次,最多出现m次
(?i)忽略后面所有字符的大小写。a((?i)b)c,表示只忽略b的大小写
public class Demo {
    public static void main(String[] args) {
        //由字母、数字、下划线组成的至少6位字符串
        System.out.println("hello_2022".matches("\\w{6,}"));	//true
        System.out.println("hi_i".matches("\\w{6,}"));			//false
        
        //由字母、数字组成的6位字符串
        System.out.println("hi2022".matches("[\\w&&[^_]]{6}"));	//true
        System.out.println("hi22".matches("[\\w&&[^_]]{6}"));	//false
    }
}

使用正则表达式一般是改写已经写好的。插件名:any-rule 。使用方法:项目窗口右键选择AnyRule

2 捕获分组

2.1 分组

表示时间的正则表达式 "([01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d"

其中([01]\\d|2[0-3])就是分的一个组, () 是表示分组的符号。

  • 每个组都是有组号的,即序号。

​ 1.组号从1开始,连续不间断。

​ 2.以左括号为基准,最左边的是第一组,以此类推。

  (  A  (  B  )  )(  C  )
// A是第一组
// B是第二组
// C是第三组

2.2 捕获分组

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

语法:

在正则表达式内部: \\X

在正则表达式外部: $X //捕获第X组的数据

在正则表达式内部

public class RegexDemo7 {
    public static void main(String[] args) {
        //判断一个字符串的开始部分与结束部分是否一致
        //q243q   12java12  @!sig@s
        String regex1 = "(.+).+\\1";
        System.out.println("q243q".matches(regex1));    //true
        System.out.println("12java12".matches(regex1)); //true
        System.out.println("@!sig@s".matches(regex1));  //false

        //判断一个字符串的开始部分与结束部分是否一致,且开始结束部分里的字符也要一致
        //000inside000  &&1002&&  0vObject0vO
        String regex2 = "((.)\\2*).+\\1";
        System.out.println("000inside000".matches(regex2)); //true
        System.out.println("&&1002&&".matches(regex2));     //true
        System.out.println("0vObject0vO".matches(regex2));  //false
    }
}

在正则表达式外部

//将重复内容替换为单个字符
//"我要吃吃吃吃吃吃吃吃饭饭饭饭饭"替换成"我要吃饭"
public class RegexDemo8 {
    public static void main(String[] args) {
        String str = "我要吃吃吃吃吃吃吃吃饭饭饭饭饭";

        // $1:在正则表达式外部使用一次分组1
        String result = str.replaceAll("(.)\\1+", "$1");
        System.out.println(result); //我要吃饭
    }
}

2.3 非捕获分组

匹配正则表达式但不捕获匹配的子表达式,即它是一个非捕获匹配,不存储供以后使用的匹配。

不占用组号

符号说明
(?:regex)获取所有
(?=regex)获取前面部分
(?!regex)获取不是指定内容的前面部分

3 爬虫

3.1 爬虫基础

爬虫,即网络爬虫,也叫做网络机器人,可以代替人们自动地在互联网中进行数据信息的采集与整理,大家可以理解为在网络上爬行的一只蜘蛛,互联网就比作一张大网,而爬虫便是在这张网上爬来爬去的蜘蛛,如果它遇到自己的猎物(所需要的资源),那么它就会将其抓取下来。

需要的类

说明
Pattern模式类,正则表达式的编译表示形式。没有公共构造方法。
Matcher对输入字符串进行解释和匹配操作,即文本匹配器。没有公共构造方法。

需要的方法

static Pattern compile(String regex)使用给定的正则表达式创建Pattern的对象。
Matcher matcher(CharSequence input)创建Pattern的对象对应的Matcher的对象。
boolean find()获取与该模式匹配的子串的开始索引和结束索引加一,[start, end+1)
String group()返回由匹配操作所获取的索引截取的子串。

对于具有输入序列 str 的匹配器 m ,表达式 m.group()str.substring(m.start(), m.end()) 是等效的。

例:

/*
在如下字符串中爬取JavaXXX
”2005年6月,在JavaOne大会上,Sun公司发布了JavaSE6。此时,Java的各种版本已经更名,已取消其中的数字2,如J2EE更名为JavaEE,J2SE更名为JavaSE,J2ME更名为JavaME。“
*/
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Demo {
    public static void main(String[] args) {
        String str = "2005年6月,在JavaOne大会上,Sun公司发布了JavaSE6。此时,Java的各种版本已经更名,已取消其中的数字2,如J2EE更名为JavaEE,J2SE更名为JavaSE,J2ME更名为JavaME。";

        //使用给定的正则表达式创建Pattern的对象
        Pattern pattern = Pattern.compile("Java\\w{2,3}");

        //创建Pattern的对象对应的模式匹配器。
        //理解:使用matcher去读取str大串,去找符合pattern规则的子串
        Matcher matcher = pattern.matcher(str);

        //利用循环打印截取到的子串
        while (matcher.find()) {
            String group = matcher.group();
            System.out.print(group + " ");
            //JavaOne JavaSE6 JavaEE JavaSE JavaME
        }
    }
}

3.2 贪婪爬取

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

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

  • Java中,默认是贪婪爬取。在数量词后加’?',就是非贪婪爬取。
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Demo {
    public static void main(String[] args) {
        String str = "abbbbbbbbbbbbbbbbbbbb";

        //贪婪爬取:尽可能多的获取数据
        Pattern p1 = Pattern.compile("ab+");
        Matcher m1 = p1.matcher(str);
        while (m1.find()) {
            String s = m1.group();
            System.out.println(s); //abbbbbbbbbbbbbbbbbbbb
        }

        //非贪婪爬取:尽可能少的获取数据
        Pattern p2 = Pattern.compile("ab+?");
        Matcher m2 = p2.matcher(str);
        while (m2.find()) {
            String s = m2.group();
            System.out.println(s); //ab
        }
    }
}

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

方法说明
public String[] matches(String regex)此字符串是否匹配给定的正则表达式
public String replaceAll(String regex, 替换成的内容)将字符串按照正则表达式规则替换,返回一个新字符串
public String[] split(String regex)将字符串按照正则表达式规则切割,返回一个字符串数组
public class Demo {
    public static void main(String[] args) {
        //1.将字符串按照正则表达式规则替换,返回一个新字符串
        String str = "汤姆asikndlkahbf是猫jkashbfkjagbf不是狗";
        String regex = "[\\w&&[^_]]+";
        String s = str.replaceAll(regex, ", ");
        System.out.println(s);			//汤姆, 是猫, 不是狗

        //2.将字符串按照正则表达式规则切割,返回一个字符串数组
        String[] arr = str.split(regex);
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i]);	//汤姆是猫不是狗
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值