韩顺平Java-第二十六章:正则表达式

2024-08-24 21:36

本文主要是介绍韩顺平Java-第二十六章:正则表达式,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一 正则表达式入门

1 极速体验正则表达式威力

在这里插入图片描述

package com.hspedu.regexp;import java.util.regex.Matcher;
import java.util.regex.Pattern;体验正则表达式的威力,给我们文本处理带来哪些便利public class Regexp_ {public static void main(String[] args) {String context="1994年6、7月间,在经历了一场历时三天的讨论之后,团队决定再一次改变了努力的目标,这次他们决" +"定将该技术应用于万维网。他们认为随着Mosaic浏览器的到来,因特网正在向同样的高度互动的远景演变,而这一" +"远景正是他们在有线电视网中看到的。作为原型,帕特里克·诺顿写了一个小型万维网浏览器WebRunner。 [8] \n" +"1995年,互联网的蓬勃发展给了Oak机会。业界为了使死板、单调的静态网页能够“灵活”起来,急需一种软件技术来" +"开发一种程序,这种程序可以通过网络传播并且能够跨平台运行。于是,世界各大IT企业为此纷纷投入了大量的人力、物" +"力和财力。这个时候,Sun公司想起了那个被搁置起来很久的Oak,并且重新审视了那个用软件编写的试验平台,由于它是" +"按照嵌入式系统硬件平台体系结构进行编写的,所以非常小,特别适用于网络上的传输系统,而Oak也是一种精简的语言," +"程序非常小,适合在网络上传输。Sun公司首先推出了可以嵌入网页并且可以随同网页在网络上传输的Applet(Applet是一种" +"将小程序嵌入到网页中进行执行的技术),并将Oak更名为Java。5月23日,Sun公司在Sun world会议上正式发布Java和Ho" +"tJava浏览器。IBM、Apple、DEC、Adobe、HP、Oracle、Netscape和微软等各大公司都纷纷停止了自己的相关开发项目," +"竞相购买了Java使用许可证,并为自己的产品开发了相应的Java平台。 [9-10]  \n" +"1996年1月,Sun公司发布了Java的第一个开发工具包(JDK 1.0),这是Java发展历程中的重要里程碑,标志着Java成为一" +"种独立的开发工具。9月,约8.3万个网页应用了Java技术来制作。10月,Sun公司发布了Java平台的第一个即时(JIT)编译器。";//首先先获得一个正则表达式的对象//Pattern pattern=Pattern.compile("[a-zA-Z]+");  //获取文中所有单词//Pattern pattern = Pattern.compile("[0-9]+");    //获取文中所有数字Pattern pattern = Pattern.compile("[0-9]+|[a-zA-Z]+");  //获取文中所有数字加单词//Pattern pattern = Pattern.compile("\\d\\d\\d\\d");    其中一个\\d代表一个0-9的任意数字//创建一个匹配器对象   就是按照一个正则表达式的要求去文本中查找Matcher matcher = pattern.matcher(context);//通过循环查找所有满足条件的字符串while (matcher.find()){//如果找到,返回true 没有则falseSystem.out.println(matcher.group());	//默认值就是0 可写可不写}                                                                                                                                                                                                               }
}

二 为什么要学正则表达式

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

三 正则表达式基本介绍

1 介绍

在这里插入图片描述

2 正则表达式底层实现🚩🚩

在这里插入图片描述

package com.hspedu.regexp;import java.util.regex.Matcher;
import java.util.regex.Pattern;分析java的正则表达式的底层实现(重要.)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的应用开始普及。";//String regStr = "\\d\\d\\d\\d";String regStr = "(\\d\\d)(\\d\\d)";Pattern pattern = Pattern.compile(regStr);Matcher matcher = pattern.matcher(content);/*** matcher.find() 完成的任务* 1. 根据指定的规则,定位满足规则的子字符串(比如1998)* 2. 找到后,将子字符串的开始的索引记录到matcher对象的属性int[] groups;*    group[0] = 0, 把该子字符串的结束的索引+1的值记录到 groups[1] = 4;* 3. 同时记录 oldLast 的值为 子字符串的结束的 索引+1的值即4 即下次执行find时 就从4开始匹配** matcher.find() 完成的任务* 1. 根据指定的规则,定位满足规则的子字符串(比如(19)(98))* 2. 找到后,将子字符串的开始的索引记录到matcher对象的属性int[] groups;*    2.1 group[0] = 0, 把该子字符串的结束的索引+1的值记录到 groups[1] = 4;*    2.2 记录1组的()匹配到的字符串 groups[2] = 0 groups[3] = 2*    2.3 记录2组的()匹配到的字符串 groups[4] = 2 groups[5] = 4* 3. 同时记录 oldLast 的值为 子字符串的结束的 索引+1的值即4 即下次执行find时 就从4开始匹配*/while (matcher.find()) {System.out.println("找到:" + matcher.group(0));System.out.println("找到:" + matcher.group(1));//表示匹配到的子字符串的第一组子串System.out.println("找到:" + matcher.group(2));//表示匹配到的子字符串的第二组子串}}
}

在这里插入图片描述

四 正则表达式语法

1 元字符(转义符)

在这里插入图片描述

需要用到转移符号的字符有以下:. + ( ) $ [ ] ^ { }

package com.hspedu.regexp;import java.util.regex.Matcher;
import java.util.regex.Pattern;演示转义字符的使用public class RegExp02 {public static void main(String[] args) {String content = "abc$(a.bc(123(";//匹配( = \\(//匹配. = \\.String regStr = "\\."; //如果不加前面两个\\则代表匹配所有的字符//String regStr = "ddd";//在每个d前面加\\,则代表匹配3个连续任意数字,不加则匹配3个d//String regStr = "\\d{3}";//如果不加前面两个\\则代表匹配3个d,加上则匹配三个连续任意数字Pattern pattern = Pattern.compile(regStr);Matcher matcher = pattern.matcher(content);while (matcher.find()) {System.out.println("找到"  + matcher.group(0));}}
}
(1)限定符

用于指定其前面的字符和组合项连续出现多少次。

在这里插入图片描述

在这里插入图片描述

public static void main(String[] args) {String content = "11111111aaaaaaahello";//String regStr = "a{3}";// 匹配 aaa//String regStr = "1{4}";// 匹配 1111//String regStr = "\\d{2}";// 匹配 两位任意数字字符//Java默认匹配多的(贪婪匹配)//String regStr = "a{3,4}";// 匹配 aaa 或 aaaa(优先)//String regStr = "1{4,5}";// 匹配 1111 或 11111(优先)//String regStr = "\\d{2,5}";// 匹配 2位数 或 3,4,5 实际 sout (找到 11111 (换行) 找到 111)//String regStr = "1+";// 匹配 1个1 或 多个1//String regStr = "\\d+";// 匹配 1个数字 或 多个数字//String regStr = "1*"; // 匹配0个1或者多个1String regStr = "a1?";// 匹配 a 或 a1Pattern pattern = Pattern.compile(regStr, Pattern.CASE_INSENSITIVE);Matcher matcher = pattern.matcher(content);while (matcher.find()) {System.out.println("找到 " + matcher.group(0));}
}
(2)选择匹配符

在匹配某个字符串的时候是选择性的,即:既可以匹配这个,又可以匹配那个,这时候你需要用到选择匹配符号 。

在这里插入图片描述

public static void main(String[] args) {String content = "hanshunping|韩|寒冷";String regStr = "hanshunping";//String regStr = "韩";//String regStr = "寒冷";Pattern pattern = Pattern.compile(regStr, Pattern.CASE_INSENSITIVE);Matcher matcher = pattern.matcher(content);while (matcher.find()) {System.out.println("找到"  + matcher.group(0));}}
(3)分组组合符

a 常用分组

在这里插入图片描述

public static void main(String[] args) {String content = "hanshunping s7789 nn1189han";//String regStr = "(\\d\\d)(\\d\\d)";//匹配四个数组的字符串(7789)(1189)//String regStr = "(\\d\\d)(\\d)(\\d)";/*** 找到 7789* 第一个分组 77* 第二个分组 8* 第三个分组 9* 找到 1189* 第一个分组 11* 第二个分组 8* 第三个分组 9*/String regStr = "(?<g1>\\d\\d)(?<g2>\\d\\d)";/*** 找到 7789* 第一个分组[编号] 77* 第二个分组[编号] 89* 找到 1189* 第一个分组[编号] 11* 第二个分组[编号] 89*/Pattern pattern = Pattern.compile(regStr);Matcher matcher = pattern.matcher(content);while (matcher.find()) {System.out.println("找到 " + matcher.group(0));//System.out.println("第一个分组 " + matcher.group(1));System.out.println("第一个分组[编号] " + matcher.group("g1"));//System.out.println("第二个分组 " + matcher.group(2));System.out.println("第二个分组[编号] " + matcher.group("g2"));//System.out.println("第三个分组 " + matcher.group(3));}
}

b 特别分组

在这里插入图片描述

在这里插入图片描述

public static void main(String[] args) {String content = "hello韩顺平教育 Jack韩顺平老师 韩顺平同学hello";//找到 韩顺平教育 、 韩顺平老师 、 韩顺平同学//String regStr = "韩顺平(?:教育|老师|同学)";//不能group(1)//找到 韩顺平教育中的韩顺平 韩顺平老师中的韩顺平//String regStr = "韩顺平(?=教育|老师)";//找到 不是韩顺平教育中的韩顺平 不是韩顺平老师中的韩顺平String regStr = "韩顺平(?!教育|老师)";Pattern pattern = Pattern.compile(regStr);Matcher matcher = pattern.matcher(content);while (matcher.find()) {//非捕获分组 不能使用group(1)System.out.println("找到 " + matcher.group(0));}
}
(4)字符匹配符

在这里插入图片描述

在这里插入图片描述

应用实例

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

public static void main(String[] args) {String content = "a11c8abcABCCy @";//String regStr = "[a-z]";//匹配 a-z之间任意一个字符//String regStr = "[A-Z]";//匹配 A-Z之间任意一个字符//String regStr = "abc";//匹配 abc 字符串[默认区分大小写]//String regStr = "(?i)abc";//匹配 abc 字符串[不区分大小写]//String regStr = "[0-9]";//匹配 0-9 之间任意一个字符//String regStr = "[^a-z]";//匹配 不在 a-z之间任意一个字符//String regStr = "[^0-9]";//匹配 不在 0-9之间任意一个字符//String regStr = "[abcd]";//匹配 在 abcd中任意一个字符//String regStr = "\\D";//匹配 不在 0-9的任意一个字符//String regStr = "\\w";//匹配 大小写英文字母, 数字,下划线//String regStr = "\\W";//匹配 等价于 [^a-zA-Z0-9_]//\\s 匹配任何空白字符(空格,制表符等)//String regStr = "\\s";//\\S 匹配任何非空白字符 ,和s刚好相反//String regStr = "\\S";//.  匹配出 \n 之外的所有字符,如果要匹配.本身则需要使用 \\.String regStr = ".";//说明//1. 当创建Pattern对象时,指定 Pattern.CASE_INSENSITIVE, 表示匹配是不区分字母大小写.Pattern pattern = Pattern.compile(regStr, Pattern.CASE_INSENSITIVE);Matcher matcher = pattern.matcher(content);while (matcher.find()) {System.out.println("找到"  + matcher.group(0));}
}

非贪婪匹配

在这里插入图片描述

public static void main(String[] args) {String content = "hello111111 ok";//String regStr = "\\d+"; //默认是贪婪匹配String regStr = "\\d+?"; //非贪婪匹配Pattern pattern = Pattern.compile(regStr);Matcher matcher = pattern.matcher(content);while (matcher.find()) {System.out.println("找到"  + matcher.group(0));}
}
(5)定位符

​ 定位符,规定要匹配的字符串出现的位置,比如在字符串的开始还是结束的位置,这个也是相当有用的。

在这里插入图片描述

public static void main(String[] args) {//String content = "123anj-556abc-945BGh";//String content = "123-ljj";String content = "hanshunping sphan nnhan";//String regStr = "^[0-9]+[a-z]*";// 找到123anj//String regStr = "^[0-9]+\\-[a-z]+$";// 找到123-ljj//String regStr = "^[0-9]+\\-[a-z]+$";// 找到123-ljj//String regStr = "han\\b";// 找到 han (sphan) 找到 han (nnhan)String regStr = "han\\B";// 找到 han (hanshunping)Pattern pattern = Pattern.compile(regStr);Matcher matcher = pattern.matcher(content);while (matcher.find()) {System.out.println("找到 " + matcher.group(0));}
}

五 正则表达式三个常用类

在这里插入图片描述

1 Pattern类
(1)matches方法

用于整体匹配,在验证输入的字符串是否满足条件时使用。

 public static void main(String[] args) {String content = "hello abc hello, 韩顺平教育";//String regStr = "hello";String regStr = "hello.*";boolean matches = Pattern.matches(regStr, content);System.out.println("整体匹配="  + matches);}
2 Matcher类

在这里插入图片描述

在这里插入图片描述

public static void main(String[] args) {String content = "hello edu jack hspedutom hello smith hello hspedu hspedu";String regStr = "hello";Pattern pattern = Pattern.compile(regStr);Matcher matcher = pattern.matcher(content);while (matcher.find()) {System.out.println("=================");System.out.println(matcher.start());System.out.println(matcher.end());System.out.println("找到"  + content.substring(matcher.start(), matcher.end()));}//整体匹配方法,常用于,去校验某个字符串是否满足某个规则System.out.println("整体匹配=" + matcher.matches());//完成如果content 有 hspedu 替换成 韩顺平教育regStr = "hspedu";pattern = Pattern.compile(regStr);matcher = pattern.matcher(content);//注意:返回的字符串才是替换后的字符串 原来的 content 不变化String newContent = matcher.replaceAll("韩顺平教育");System.out.println("newContent=" + newContent);System.out.println("content=" + content);
}
3 PatternSyntaxException类

六 分组、捕获、反向引用

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

public static void main(String[] args) {String content = "hello hspedu11111 hello22 12345-111222333";//找到两个连续相同的数字//String regStr = "(\\d)\\1";//找到五个连续相同的数字//String regStr = "(\\d)\\1{4}";//找到个位与千位相同 十位与百位相同的数字//String regStr = "(\\d)(\\d)\\2\\1";//找到以下格式 "五位数-九位数连续每三位相同(例如:12345-111222333)"String regStr = "\\d{5}-(\\d)\\1{2}(\\d)\\2{2}(\\d)\\3{2}";Pattern pattern = Pattern.compile(regStr);Matcher matcher = pattern.matcher(content);while (matcher.find()) {System.out.println("找到 " + matcher.group(0));}
}

七 String类中使用正则表达式

1 替换功能

在这里插入图片描述

public static void main(String[] args) {String content = "2000年5月,JDK1.3、JDK1.4和J2SE1.3相继发布,几周后其\" + " +"获得了Apple公司Mac OS X的工业标准的支持。2001年9月24日,J2EE1.3发布。" +"2002年2月26日,J2SE1.4发布。自此Java的计算能力有了大幅提升";//使用正则表达式方式,将 JDK1.3 和 JDK1.4 替换成JDKcontent = content.replaceAll("JDK1.3|JDK1.4", "JDK");System.out.println(content);
}
2 判断功能

在这里插入图片描述

public static void main(String[] args) {String content = "13888889999";if (content.matches("1(38|39)d{8}")) {System.out.println("验证成功");} else {System.out.println("验证失败");}
}
3 分割功能

在这里插入图片描述

public static void main(String[] args) {//要求按照 # 或者 - 或者 ~ 或者 数字 来分割System.out.println("===================");content = "hello#abc-jack12smith~北京";String[] split = content.split("#|-|~|\\d+");for (String s : split) {System.out.println(s);}
}

八 正则应用案例

在这里插入图片描述

public static void main(String[] args) {String content = "13588889999";//汉字//String regStr = "^[\u0391-\uffe5]+$";//邮政编码//要求:1.是1-9开头的一个六位数.  比如:123890//     2.//     3.//String regStr = ^[1-9]\\d{5}$;//QQ号码//要求  是1-9开头的一个(5位数-10位数)  比如  12389 , 1345687 , 187698765//String regStr = "^[1-9]\\d{4,9}$";//手机号码//要求 必须以13,14,15,18 开头的11位数 , 比如 13588889999String regStr = "^1[3|4|5|8]\\d{9}$";Pattern pattern = Pattern.compile(regStr);Matcher matcher = pattern.matcher(content);if(matcher.find()) {System.out.println("满足格式");} else {System.out.println("不满足格式");}}
public static void main(String[] args) {//String content = "https://www.bilibili.com/video/BV1fh411y7R8?";String content = "https://blog.csdn.net/wthsoso/article/details/136381971";/** ((http|https)://)开始部分*  ([\w-]+\.)+[\w-]+ 匹配 www.bilibili.com*  (\/[\w-?=&/%.#]*)? 匹配 /video/BV1fh411y7R8?p=894&vd_source=a8223634aa8a190c7233a2dc3f8a15e3*  []里面的元素相当于一个集合*  如果查找 "(去掉http)edu.metastudy.vip/mt/official/pc/mxmt-ksjhdj"*  regStr = "^((http|https)://)?([\\w-]+\\.)+[\\w-]+(\\/[\\w-?=&/%.#]*)?$";*/String regStr = "^((http|https)://)([\\w-]+\\.)+[\\w-]+(\\/[\\w-?=&/%.#]*)?$";Pattern pattern = Pattern.compile(regStr);Matcher matcher = pattern.matcher(content);if (matcher.find()) {System.out.println("true");} else {System.out.println("false");}}

在这里插入图片描述

public static void main(String[] args) {String content = "我....我要....学学学学....编程java!";//去掉所有的 .Pattern pattern = Pattern.compile("\\.");Matcher matcher = pattern.matcher(content);content = matcher.replaceAll("");System.out.println("content=" + content);//去掉重复的字 (.)查找任意的字符 \\1反向引用出'(.)'的内容 +指重复多次 $1表示重复字符替换为1个//如果要替换ABAB型 例如"我要我要" 使用(..)\\1+content = Pattern.compile("(.)\\1+").matcher(content).replaceAll("$1");System.out.println("content=" + content);
}

这篇关于韩顺平Java-第二十六章:正则表达式的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1103668

相关文章

JVM 的类初始化机制

前言 当你在 Java 程序中new对象时,有没有考虑过 JVM 是如何把静态的字节码(byte code)转化为运行时对象的呢,这个问题看似简单,但清楚的同学相信也不会太多,这篇文章首先介绍 JVM 类初始化的机制,然后给出几个易出错的实例来分析,帮助大家更好理解这个知识点。 JVM 将字节码转化为运行时对象分为三个阶段,分别是:loading 、Linking、initialization

Spring Security 基于表达式的权限控制

前言 spring security 3.0已经可以使用spring el表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。 常见的表达式 Spring Security可用表达式对象的基类是SecurityExpressionRoot。 表达式描述hasRole([role])用户拥有制定的角色时返回true (Spring security默认会带有ROLE_前缀),去

浅析Spring Security认证过程

类图 为了方便理解Spring Security认证流程,特意画了如下的类图,包含相关的核心认证类 概述 核心验证器 AuthenticationManager 该对象提供了认证方法的入口,接收一个Authentiaton对象作为参数; public interface AuthenticationManager {Authentication authenticate(Authenti

Spring Security--Architecture Overview

1 核心组件 这一节主要介绍一些在Spring Security中常见且核心的Java类,它们之间的依赖,构建起了整个框架。想要理解整个架构,最起码得对这些类眼熟。 1.1 SecurityContextHolder SecurityContextHolder用于存储安全上下文(security context)的信息。当前操作的用户是谁,该用户是否已经被认证,他拥有哪些角色权限…这些都被保

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

Java架构师知识体认识

源码分析 常用设计模式 Proxy代理模式Factory工厂模式Singleton单例模式Delegate委派模式Strategy策略模式Prototype原型模式Template模板模式 Spring5 beans 接口实例化代理Bean操作 Context Ioc容器设计原理及高级特性Aop设计原理Factorybean与Beanfactory Transaction 声明式事物

Java进阶13讲__第12讲_1/2

多线程、线程池 1.  线程概念 1.1  什么是线程 1.2  线程的好处 2.   创建线程的三种方式 注意事项 2.1  继承Thread类 2.1.1 认识  2.1.2  编码实现  package cn.hdc.oop10.Thread;import org.slf4j.Logger;import org.slf4j.LoggerFactory

JAVA智听未来一站式有声阅读平台听书系统小程序源码

智听未来,一站式有声阅读平台听书系统 🌟&nbsp;开篇:遇见未来,从“智听”开始 在这个快节奏的时代,你是否渴望在忙碌的间隙,找到一片属于自己的宁静角落?是否梦想着能随时随地,沉浸在知识的海洋,或是故事的奇幻世界里?今天,就让我带你一起探索“智听未来”——这一站式有声阅读平台听书系统,它正悄悄改变着我们的阅读方式,让未来触手可及! 📚&nbsp;第一站:海量资源,应有尽有 走进“智听

在cscode中通过maven创建java项目

在cscode中创建java项目 可以通过博客完成maven的导入 建立maven项目 使用快捷键 Ctrl + Shift + P 建立一个 Maven 项目 1 Ctrl + Shift + P 打开输入框2 输入 "> java create"3 选择 maven4 选择 No Archetype5 输入 域名6 输入项目名称7 建立一个文件目录存放项目,文件名一般为项目名8 确定