2021-06-30


参考文献: https://www.bilibili.com/video/BV1Eq4y1E79W

一. 为什么要学习正则表达式

1.提取文章中的所有英文单词
2.提取文章中的所有数字
3.提取微博热搜的所有标题
4.检测用户的输入(邮箱,电话号码)是否正确
为了解决上述的问题,Java提供了正则表达式技术,专门用来处理类似的文本问题。简单来说,正则表达式是对字符串执行模式匹配技术。

二. 正则表达式语法

1.元字符-转意字符 \\

\\ :在使用正则表达式检索某一些特殊字符的时候,需要用到特殊字符,例如检索"asd("时就需要使用转义字符,否则检索不到结果,且在正则表达式中两个 \\ 代表其他语言中的一个 \。
需要用到转义字符的有如:.*+()$/?[]^{}

2. 元字符-字符匹配符

表1:

符号符号示例解释
[ ]可以接收的字符列表[abcd]a,b,c,d中任意一个字符
^不可接收的字符列表[^abcd]除a,b,c,d外的任意一个字符,包括数字,特殊字符,英文字母
-连字符[a-z]任意单个小写字母
|匹配 "|"之前或之后的表达式ab| cdab或者cd

表2:

符号含义示例说明匹配输入
.匹配除\n外的任意字符c..d以c开头,d结尾中间包括任意两个字符长度未4的字符串cdbd,cshd
\\d匹配单个字符,相当于[0-9]\\{3} (\\d)?包含3个或者4个数字的字符串123,2434
\\D匹配单个非数字字符,相当于[^0-9](\\d)+\\D一个或者多个数字开头后面接一个非数字字符1%,32(
\\w匹配单个数字,大小写字母字符相当于[0-9a-zA-Z]\\d{3}\\w{4}以三个数字开头长度为7的数字字母字符串123a3bd,563asd5
\\W匹配单个非数字,大小写字母相当于[^0-9a-zA-Z]\\W\\d{2}以一个非数字字母开头两个数字结尾的字符串$12,^34
*指定字符重复0次或n次(无要求零到多)(abc)*仅包含任意个abc的字符串,等效于\w*abc,abcabc
+指定字符重复1次或n次 (至少1次)1到多m+(abc)*至少以1个m开头,后面你接任意个abcmabc,mmabcabc
?指定字符重复0次或1次(最多1次)m+abc?至少以1个m开头 后接ab或者abcmab,mmabc
{n}只能输入n个字符[abcd]{3}由abc组成任意3个字符串aaa,bbb
{n.}指定至少n个匹配[abcd]{3,}由abcd组成的任意长度不小于3的字符串aaa,aadcd
{n,m}指定至少个但不多于m个匹配[abcd]{3,4}由abcd组成的任意长度不小于3不大于5的字符串acd,abcd,aaaa

三. 字符匹配符含义说明

  1. [a-z]
    表示可以匹配a-z中任意一个字符,比如使用[a-z]去匹配a123c会得到a,c。
  2. Java正则表达式默认是区分大小写的,如何使其不区分大小写
  • (?!)abc 表示abc都不区分大小写
  • a(?!)bc 表示bc都不区分大小写
  • a((?!)b)c 表示只有b不区分大小写
  1. [ ^a-z ]说明:
    [ ^a-z ]表示可以匹配不是a-z中的任意一个字符,比如使用[ ^a-z ]去匹配 ab237(c 会得到结果237(,[^A-Z]同理。
  • \\d 表示匹配0-9中任意一个数字
  • \\D 表示可以匹配不是0-9中的任意一个数字
  • \\w 表示匹配任意英文字符,数字和下划线相当于[0-9a-zA-z_]
  • \\W 相当于[ ^0-9a-zA-z_ ]
  • \\s 匹配任意空白字符(空格,制表符)
  • \\S 匹配任意非空白字符,和\\s刚好相反
  1. 元字符-定位符
符号含义示例说明匹配输入
^指定起始字符^ [ 0-9 ]+[a-z]*以至少一个数字开头,后接任意个小写字母的字符串123,6ac
$指定结束字符1\\-[a-z]$以1个数字开头后接连字符"-",并以至少一个小写字母结尾的字符串1-a,2-c
\\b匹配字符串的边界han\b边界的意思是子串间有空格,或者是目标串的结束位置hanshupi sphan nnhan
\B匹配目标字符串的非边界han\Bhanshupi sphan nnhan
  1. 正则表达式分组
常用分组构造形式说明
(pattern)非命名捕获,捕获匹配的子字符串,编号为零的第一个捕获是由整个正则表达式匹配的文本,其他捕获结果则根据左括号的顺序从1开始编号
(?<name> pattern)命明捕获,将匹配的子字符串捕获到一个组名称或编号名称中。用于name的字符串不能包含标点符号且不能以数字开头。可以使用单引号代替尖括号,例如(?‘name’)
(?:pattern)匹配 pattern 但不捕获该匹配的子表达式,即它是一个非捕获匹配,不存储供以后使用的匹配,这对于用"or"字符(|)组合模式部件的情况很有用。例如industr(?:y|ies) 是比 ‘industry| industries’ 更经济的表达式
(?=pattern)它是一个非捕获匹配。例如’Windows (?=95|98|NT|2000)’ 匹配 "Windows 2000"中的 “Windows”,但不匹配 “Windows 3.1"中的"Windows”。
(?!pattern)该表达式匹配不处于匹配 pattern 的字符串的起始点的搜索字符串。它是一个非捕获匹配。例如’Windows(?!95|98|NT|2000)’ 匹配 “Windows 3.1"中的"windows”, 但不匹配"Windows 2000"中的"Windows"。

四. 分组、捕获 、反向引用

  1. 提出需求
    找出一段文本中的四个数字连在一起的子串,满足第1位与第4位相同,第2位与第3位相同,比如1221,5775,…
  2. 分组
    可以使用圆括号组成分组,一个圆括号的部分我们可以看作一个子表达式的一个分组。
  3. 捕获
    把正则表达式中子表达式/分组匹配的的内容,保存到内存中以数字编号或显示命明的组里,方便后面引用,从左向右,以分组的左括号为标志,第一个出现的分组的组号为1,第二个为2,以此类推。组0表示整个表达式。
  4. 反向引用
    圆括号的内容被捕获后,可以在这个括号后被使用,从而写出一个比较实用的匹配模式,这个称为反向引用。这种引用既可以是写在正则表达式的内部,也可以是写在正则表达式的外部,反向引用\\分组号,外部引用$分组号。
    案例
  • 匹配两个连续的相同数字
  • 匹配五个连续相同的数字
  • 匹配个位与千位相同,十位与百位相同的数,5115,1771

五. 案例

  1. 案例1
String content = "a11c8";
        String repStr = "[a-z]";
        Pattern compile = Pattern.compile(repStr);
        Matcher matcher = compile.matcher(content);
        while (matcher.find()){
            System.out.print(matcher.group(0) + " ");
        }

运行结果:
在这里插入图片描述
2. 案列2

		String content = "adjha1123 asd5678";
        String RepStr = "(?<g1>\\d\\d)(?<g2>\\d\\d)";
        Pattern pattern = Pattern.compile(RepStr);
        Matcher matcher = pattern.matcher(content);
        while (matcher.find()){
            System.out.print(matcher.group(1) + " ");
            System.out.print(matcher.group("g1") + " ");
            System.out.print(matcher.group(2) + " ");
            System.out.println(matcher.group("g2"));
        }

运行结果:
在这里插入图片描述
3. 案例3

		String content = "https://www.bilibili.com/video/BV1Eq4y1E79W?p=17";
        String repStr = "^((https|http)://)([\\w-]+\\.)+[\\w]+(\\/[\\w?=/-]*)?$";
        Pattern pattern = Pattern.compile(repStr);
        Matcher matcher = pattern.matcher(content);

        if(matcher.find()) {
            System.out.println("满足匹配");
        } else {
            System.out.println("不满足匹配");
        }
        //整体匹配
        System.out.println("");
        //使用一个整体来匹配
        boolean matches = Pattern.matches(repStr, content);

运行结果:
满足匹配

  1. 案例4
		String content= "hello world jack nice look loop overLook hello hello";
        String repStr = "hello";
        //替换将一个字符全部替换成另一个字符
        String newStr = "hello";
        Pattern pattern1 = Pattern.compile(newStr);
        Matcher matcher1 = pattern1.matcher(content);
        System.out.println(matcher1.replaceAll("牛逼"));

运行结果:
在这里插入图片描述
5. 案例5

        String content = "jac11k john work 1551look 2332hard 6776extraordinary";
        String content = "12345-999888000";
        String expStr = "(\\d)\\1";  //查找到两个相同的数据
        String expStr1 = "(\\d)(\\d)\\2\\1";// 查找第一位与第四位相同的数据
        //判断数据引用的时候应该判断其是否有括号 如果有的话应该\\2判断位置
        String expStr2 = "\\d{5}-(\\d)\\1{2}(\\d)\\2{2}(\\d)\\3{2}";  //判断content是否满足格式
        Pattern pattern = Pattern.compile(expStr2);
        Matcher matcher = pattern.matcher(content);
        while (matcher.find()) {
            System.out.println(matcher.group(0));
        }

运行结果:
在这里插入图片描述
6. 案例6

		String content = "我我....要.....学学学学Java!";
        String repStr = "";
        Pattern compile = Pattern.compile("[.]*");
        Matcher matcher = compile.matcher(content);
        while (matcher.find()){
            System.out.println(matcher.group(0));
        }
        //首先找到需要去除的数据
        content = matcher.replaceAll("");
        System.out.println(content);
        //将重复的数据去除
        Pattern compile1 = Pattern.compile("(.)\\1+");
        Matcher matcher1 = compile1.matcher(content);
        //使用外部引用计算
//        content = matcher1.replaceAll("$1");
//        System.out.println(content);
        //使用一句话来计算
        content = Pattern.compile("(.)\\1+").matcher(content).replaceAll("$1");
        System.out.println(content);

        //直接匹配
        content = "13990909090";
        if(content.matches("(138|139)\\d{8}")) {
            System.out.println("验证成功");
        } else {
            System.out.println("验证失败");
        }
        content = "jack$keen?pool#1234+asd";
        String[] split = content.split("$|#|\\?|\\+");
        for (String s : split) {
            System.out.println(s);
        }

运行结果:
在这里插入图片描述


  1. 0-9 ↩︎

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值