Java 正则表达式总结 2022/2/20

1 开胃小菜

1.1 提取文章中所有的英文单词

/*
 * 
 */
package regexp;

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

/**
 * 体验正则表达式的威力,给我们文本处理带来哪些便利
 *
 * @author Aldous_Rowe
 * @since 2021/11/23
 */
public class Regexp_ {
   
    public static void main(String[] args) {
   
        // 假定,编写了爬虫,从百度页面得到如下文本
        String content = "1995年,互联网的蓬勃发展给了Oak机会。业界为了使死板、单调的静态网页能够“灵活”起来,急需一种软件技术来开发一种程序,这种程序可以通过网络传播并且能够跨平台运行。于是,世界各大IT企业为此纷纷投入了大量的人力、物力和财力。这个时候,Sun公司想起了那个被搁置起来很久的Oak,并且重新审视了那个用软件编写的试验平台,由于它是按照嵌入式系统硬件平台体系结构进行编写的,所以非常小,特别适用于网络上的传输系统,而Oak也是一种精简的语言,程序非常小,适合在网络上传输。Sun公司首先推出了可以嵌入网页并且可以随同网页在网络上传输的Applet(Applet是一种将小程序嵌入到网页中进行执行的技术),并将Oak更名为Java(在申请注册商标时,发现Oak已经被人使用了,再想了一系列名字之后,最终,使用了提议者在喝一杯Java咖啡时无意提到的Java词语)。5月23日,Sun公司在Sun world会议上正式发布Java和HotJava浏览器。IBM、Apple、DEC、Adobe、HP、Oracle、Netscape和微软等各大公司都纷纷停止了自己的相关开发项目,竞相购买了Java使用许可证,并为自己的产品开发了相应的Java平台。";
        // 提取文章中所有的英文单词
        // (1)传统方法,使用遍历方式,代码量大,效率不高
        // (2)正则表达式技术

        // 1.先创建一个 Pattern 对象,模式对象,可以理解成就是一个正则表达式对象
        Pattern pattern = Pattern.compile("[a-zA-Z]+");
        // 2.创建一个匹配器对象
        // 理解:就是 matcher 匹配器按照 pattern(模式/样式),到 content 文本中去匹配
        // 找到就返回 true,否则就返回 false
        Matcher matcher = pattern.matcher(content);
        // 3.可以开始循环匹配
        while (matcher.find()) {
   
            // 匹配内容,文本,放到 m.group(0)
            System.out.println("找到:" + matcher.group(0));
        }
    }
}

1.2 提取文章中所有的数字

Pattern pattern = Pattern.compile("[0-9]+");

1.3 提取文章中所有的英文单词和数字

Pattern pattern = Pattern.compile("([0-9]+)|([a-zA-Z]+)");

1.5 提取IP地址

/*
 * 
 */
package regexp;

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

/**
 * @author Aldous_Rowe
 * @since 2021/11/23
 */
public class IP地址 {
   
    public static void main(String[] args) {
   
        String content = "私有地址(Private address)属于非注册地址,专门为组织机构内部使用。\n" +
                "以下列出留用的内部私有地址\n" +
                "A类 10.0.0.0--10.255.255.255\n" +
                "B类 172.16.0.0--172.31.255.255\n" +
                "C类 192.168.0.0--192.168.255.255";
        Pattern pattern = Pattern.compile("\\d+\\.\\d+\\.\\d+\\.\\d+");
        int no = 0;
        Matcher matcher = pattern.matcher(content);
        while (matcher.find()) {
   
            System.out.println("找到:" + (++no) + " " + matcher.group(0));
        }
    }
}

运行结果:

找到:1 10.0.0.0
找到:2 10.255.255.255
找到:3 172.16.0.0
找到:4 172.31.255.255
找到:5 192.168.0.0
找到:6 192.168.255.255

2 正则表达式的基本介绍

一个正则表达式,就是用某种模式去匹配字符串的一个公式。很多人因为它们看上去比较古怪而且复杂所以不敢去使用,不过,经过练习后,就觉得这些复杂的表达式写起来还是相当简单的,而且,一旦你弄懂它们,你就能把数小时辛苦而且易错的文本处理工作缩短在几分钟(甚至几秒钟)内完成

3 正则表达式的底层实现

给你一段字符串(文本),请找出所有四个数字连在一起的子串,比如:

应该找到1998 1999 3443 9889 ===> 分析底层实现 RegTheory.java

/*
 * 
 */
package regexp;

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

/**
 * 分析 Java 的正则表达式的底层实现
 *
 * @author Aldous_Rowe
 * @since 2021/11/23
 */
public class RegTheory {
   
    public static void main(String[] args) {
   
        String content = "1998年12月8日,第二代Java平台的企业版J2EE发布。1999年6月,Sun公司发布了第二代Java平台(简称为Java2)的3个版本:J2ME(Java2 Micro Edition,Java2平台的微型版),应用于移动、无线及有限资源的环境;J2SE(Java 2 Standard Edition,Java 2平台的标准版),应用于桌面环境;J2EE(Java 2Enterprise Edition,Java 2平台的企业版),应用于基于Java的应用服务器。Java 2平台的发布,是Java发展过程中最重要的一个里程碑,标志着Java的应用开始普及。";
        // 目标:匹配所有四个数字
        // 说明
        // 1. \\d 表示一个任意的数字
        String regStr = "(\\d\\d)(\\d\\d)";
        // 2. 创建模式对象【即正则表达式对象】
        Pattern pattern = Pattern.compile(regStr);
        // 3. 创建匹配器
        // 说明:创建匹配器 matcher,按照正则表达式的规则去匹配content字符串
        Matcher matcher = pattern.matcher(content);
        // 4. 开始匹配
        /*
        matcher.find() 完成的任务 (考虑分组)
           什么是分组,比如 (\d\d)(\d\d),正则表达式中有 () 表示分组,第 1 个 () 表示第 1 组,第 2 个 () 表示第 2 组...
        1. 根据指定的规则,定位满足规则的子字符串(比如 (19)(98))
        2. 找到后,将子字符串的开始的索引记录到 matcher 对象的属性 int[] groups
           2.1 groups[0] = 0,把该子字符串的结束的索引 +1 的值记录到 groups[1] = 4
           2.2 记录 1 组 () 匹配到的字符串 groups[2] = 0 groups[3] = 2
           2.3 记录 2 组 () 匹配到的字符串 groups[4] = 2 groups[5] = 4
           2.4 如果有更多的分组
        3. 同时记录 oldLast 的值为该子字符串的结束的索引 +1 的值即 4,即下次执行 find 时,就从 4 开始匹配

        matcher.group() 分析、
        源码:
        public String group(int group) {
            if (first < 0)
                throw new IllegalStateException("No match found");
            if (group < 0 || group > groupCount())
                throw new IndexOutOfBoundsException("No group " + group);
            if ((groups[group*2] == -1) || (groups[group*2+1] == -1))
                return null;
            return getSubSequence(groups[group * 2], groups[group * 2 + 1]).toString();
        }
        1. 根据 groups[0] = 0 和 groups[1] = 4 的记录的位置,从 content 开始截取子字符串返回
           就是 [0,4) 包含 0 但是不包含索引为 4 的位置

        如果再次执行 find 方法,仍然按照上面的分析来执行
         */
        while (matcher.find()) {
   
            // 小结
            // 1. 如果正则表达式有 () 即分组
            // 2. 取出匹配的字符串规则如下
            // 3. group(0) 表示匹配到的子字符串
            // 4. group(1) 表示匹配到的子字符串的第一组字符串
            // 5. group(2) 表示匹配到的子字符串的第二组字符串
            // 6. ... 但是分组的数不能越界
            System.out.println("找到:" + matcher.group(0));
            System.out.print
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值