当前位置: 首页 > news >正文

Java 黑马程序员学习笔记(进阶篇5)

常用 API

1. 正则表达式

(1) 正则表达式(Regex)是一种字符串匹配 / 处理的规则表达式,核心作用是:快速校验字符串格式(如手机号、邮箱)、提取目标内容、替换敏感字符等,避免写大量 if-else 判断,提升字符串处理效率。
(2) 适用场景:表单验证(手机号、身份证)、日志内容提取、字符串批量替换(如敏感词过滤)。

(3) 正则核心语法:

符号含义举例
[ ]里面的内容出现一次[0-9]、[a-zA-Z0-9]
( )分组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)[a-zA-Z_0-9]
\W非单词字符[^\w]

注意:Java 字符串中,\ 需转义为 \\(如 \d 要写成 \\d)。

(4) 量词(匹配多个字符,修饰前一个字符)

量词说明示例(匹配结果)
*匹配前一个字符 0 次或多次ab* → 匹配 "a"、"ab"、"abb"
+匹配前一个字符 1 次或多次ab+ → 匹配 "ab"、"abb"(不匹配 "a")
?匹配前一个字符 0 次或 1 次ab? → 匹配 "a"、"ab"(不匹配 "abb")
{n}匹配前一个字符恰好 n 次a{3} → 匹配 "aaa"
{n,}匹配前一个字符至少 n 次a{2,} → 匹配 "aa"、"aaa"
{n,m}匹配前一个字符 n 到 m 次a{2,3} → 匹配 "aa"、"aaa"

(5) 练习

题目 1:邮箱格式验证正则表达式的应用

请设计一个 Java 程序,使用正则表达式验证邮箱地址格式是否符合以下规则:

① 用户名部分:由 1 个及以上字母、数字或下划线组成

② 包含 @符号

③ 域名主体部分:由 2-6 个字母或数字组成(不能包含下划线)

④ 顶级域名部分:由 1-2 个后缀组成,每个后缀以点号 (.) 开头,且由 2-3 个字母组成(例如.com.cn.co.uk等)

⑤ 请使用正则表达式实现上述验证,并测试以下 3 个邮箱地址是否符合规则,输出匹配结果(true/false):

  • "3232323@qq.com"
  • "zhangsan@itcast.cnn"
  • "dlei0009@163.com"
public class RegexExamples {public static void main(String[] args) {// 邮箱格式验证正则表达式String regex3 = "\\w+@[\\w&&[^_]]{2,6}(\\.[a-zA-Z]{2,3}){1,2}";  System.out.println("3232323@qq.com".matches(regex3));System.out.println("zhangsan@itcast.cnn".matches(regex3));System.out.println("dlei0009@163.com".matches(regex3));}
}
关键逻辑 1:为什么 [^_] 必须用 [ ] 包裹

[^_] 中的 ^ 是 “否定” 符号,但仅在 [] 内有效,^ 这个符号在正则中有两种完全不同的含义:

  • 当 ^ 放在 [] 内部开头时,表示 “否定”,即 “排除后面的字符”。
    所以 [^_] 表示 “匹配除了下划线 _ 之外的任意一个字符”。
  • 当 ^ 不在 [] 内时,它是 “锚定符”,表示 “匹配字符串的开头位置”。
    例如 ^abc 表示 “匹配以 abc 开头的字符串”。
关键逻辑 2:为什么用 \\. 而不用 .
  • 在正则表达式中,. 是一个特殊元字符,它的含义是 “匹配除换行符之外的任意单个字符”,而不是字面意义上的点号(.)。
  • 在你的代码中,需要匹配邮箱地址中的点号(例如 .com.cn 中的点),这时候就需要将特殊元字符 . 转义为普通字符。转义的方式是在它前面加一个反斜杠 \,即 \.,这样正则引擎就会把它当作字面意义上的点号来处理。

题目 2:使用正则表达式提取文本中的特定格式内容

请设计一个 Java 程序,实现从以下文本中提取所有符合 “Java 后跟 0-2 个数字” 格式的子串(例如 “Java”“Java8”“Java11” 等):

(1) 文本内容:
"Java自从95年问世以来,经历了很多版本,目前企业中用的最多的是Java8和Java11,因为这两个是长期支持版本,下一个长期支持版本是Java17,相信在未来不久Java17也会逐渐登上历史舞台"

(2) 具体要求:

定义一个method1方法,在方法中使用正则表达式 “Java\d {0,2}” 创建PatternMatcher对象,并调用find()方法进行至少一次匹配(无需提取结果,仅执行查找操作)。

main方法中:

  • 调用method1方法处理上述文本;
  • 再次使用相同的正则表达式,通过while循环配合find()group()方法,提取并打印所有符合格式的子串。
package demo1;import java.util.regex.Matcher;
import java.util.regex.Pattern;public class test6 {public static void main(String[] args) {String str = "Java自从95年问世以来,经历了很多版本,目前企业中用的最多的是Java8和Java11," +"因为这两个是长期支持版本,下一个长期支持版本是Java17,相信在未来不久Java17也会逐渐登上历史舞台";method1(str);Pattern p = Pattern.compile("Java\\d{0,2}");  //不太理解Matcher m = p.matcher(str);  //不太理解while(m.find()) {String s = m.group();System.out.println(s);}}private static void method1(String str) {Pattern p = Pattern.compile("Java\\d{0,2}");  //不太理解Matcher m = p.matcher(str);  //不太理解boolean b = m.find();}
}
关键逻辑 1: Pattern p = Pattern.compile 的作用

(1) Pattern 是 Java 正则的 “模板类”,compile 方法的作用是把上面的正则字符串 “编译” 成一个 Pattern 对象

可以理解为:

  • 正则字符串是 “文字描述”(比如 “找一个叫 Java、后面最多带 2 个数字的内容”);
  • Pattern 对象是 “实体模板”(根据文字描述制作的一个 “模具”,可以反复用来检查字符串)。

(2) 编译的好处是:如果需要多次使用同一个正则(比如在循环或多个方法中),编译一次后复用 Pattern 对象,能提高效率。

关键逻辑 2:理解 Matcher m = p.matcher(str);
(1) Matcher 是什么?

Matcher 是 Java 正则的 “执行者”,它的作用是:

  • 拿着 Pattern 模板(比如 “找 Java+0-2 个数字”);
  • 去扫描目标字符串 str(你定义的那段关于 Java 版本的文本);
  • 找到符合模板的子串,并提供提取这些子串的方法(比如 group())。
(2) p.matcher(str) 的含义

p 是我们前面编译好的 Pattern 模板,str 是要检查的目标文本。p.matcher(str) 就相当于 “用模板 p 去适配文本 str”,返回的 Matcher 对象 m 就是这个 “适配工具”。

关键逻辑 3:先理解 m.find() 的作用

m 是前面创建的 Matcher 对象(匹配器),find() 方法的功能是:
从当前位置开始,在目标文本中查找 “下一个” 符合正则规则的子串

  • 返回 true:表示找到了一个匹配项,同时内部指针会 “移动到这个匹配项的末尾”(下次调用 find() 会从这里继续往后找)。
  • 返回 false:表示从当前位置往后,再也没有符合规则的子串了。
关键逻辑 4:m.group() 的作用

(1) 当 m.find() 返回 true 时(表示找到了一个匹配项),m.group() 用于获取当前找到的那个 “匹配子串”

(2) 可以理解为:find() 负责 “发现目标”,group() 负责 “取出目标”。

题目 3:有条件的爬取数据

问题描述
(1) 给定一段关于 Java 版本发展的文本:
"Java 自从 95 年问世以来,经历了很多版本,目前企业中用的最多的是 Java8 和 Java11,因为这两个是长期支持版本,下一个长期支持版本是 Java17,相信在未来不久 Java17 也会逐渐登上历史舞台"

(2) 请编写 Java 程序,从这段文本中提取所有 "Java" 字符串,但要求这些 "Java" 后面必须紧跟着 "8"、"11" 或 "17"(即仅匹配 "Java8"、"Java11"、"Java17" 中的 "Java" 部分),并将提取到的 "Java" 依次打印输出。

package demo1;import java.util.regex.Matcher;
import java.util.regex.Pattern;public class test11 {public static void main(String[] args) {String s ="Java自从95年问世以来,经历了很多版本,目前企业中用的最多的是Java8和Java11," +"因为这两个是长期支持版本,下一个长期支持版本是Java17,相信在未来不久Java17也会逐渐登上历史舞台";String regex = "Java(?=8|11|17)";   //不太理解Pattern p = Pattern.compile(regex);Matcher m = p.matcher(s);while(m.find()) {System.out.println(m.group());}}
}
关键逻辑 2:代码里 ?= 的作用

(1) ?= 是正则表达式中正向预查(Positive Lookahead) 的语法标记,核心作用是:

(2) 判断当前位置后面是否紧跟着符合特定规则的内容,但不会将这些内容包含在匹配结果中(仅做条件检查,不消耗字符)。

以你的代码为例:Java(?=8|11|17)
这里的 (?=8|11|17) 表示:

  • 检查 “Java” 后面是否紧跟着 “8”“11” 或 “17”;
  • 如果符合条件,就匹配 “Java”;
  • 但最终的匹配结果里只包含 “Java”,后面的 “8”“11”“17” 不会被包含进来(仅作为匹配条件)。
题目 4:提取不区分大小写的 Java 版本完整字符串

问题描述
给定一段描述 Java 版本发展的文本:
"Java 自从 95 年问世以来,经历了很多版本,目前企业中用的最多的是 Java8 和 Java11,因为这两个是长期支持版本,下一个长期支持版本是 Java17,相信在未来不久 Java17 也会逐渐登上历史舞台"

请编写 Java 程序,从这段文本中提取所有满足以下条件的完整字符串

(1) 包含 “Java”(不区分大小写,即 “Java”“java”“JAVA” 等形式都需匹配,本题文本中仅含 “Java”);

(2) “Java” 后面必须紧跟 “8”“11” 或 “17”(即需匹配 “Java8”“Java11”“Java17” 这类完整组合)。

(3) 最终需将提取到的完整字符串依次打印输出。

String regex2 = "((?i)Java)(?:8|11|17)";   
关键逻辑:?: 的作用

(1) ?: 是正则表达式中 “非捕获组(Non-capturing Group)” 的语法标记,作用是将多个子表达式 “打包” 成一个整体进行匹配,但不保存该组的匹配结果(即不会占用捕获组的编号,也无法通过 group(n) 方法引用)。

(2) 非捕获组的本质是 “工具性分组”,它的唯一目的是将多个元素(如选项、重复模式等)视为一个整体,方便使用 |(或)、*(任意次)、+(至少一次)等量词修饰。

(3) 例子说明:

假设需要匹配 “Java8”“Java11”“Java17” 这三种字符串:

用非捕获组:Java(?:8|11|17)

  • 这里 (?:8|11|17) 将 “8”“11”“17” 打包成一个整体选项,确保 “Java” 后面只能接这三个值。
  • 匹配结果是完整的 “Java8”“Java11” 等,但 “8”“11”“17” 不会被单独保存为捕获组。

文章转载自:

http://uyTaTunl.hyhqd.cn
http://fssJhJXN.hyhqd.cn
http://geJwNYnV.hyhqd.cn
http://cGrzdCYk.hyhqd.cn
http://UyLyL5vG.hyhqd.cn
http://dNP21cue.hyhqd.cn
http://1w09RmGg.hyhqd.cn
http://po6Bpty1.hyhqd.cn
http://QeL4WaW0.hyhqd.cn
http://pGbbSEMI.hyhqd.cn
http://k50KI82P.hyhqd.cn
http://067cMjhM.hyhqd.cn
http://v1pwxomq.hyhqd.cn
http://xeu8fedB.hyhqd.cn
http://KPKT2YnM.hyhqd.cn
http://Gij9A6IR.hyhqd.cn
http://boB5FngZ.hyhqd.cn
http://mz8d5ufN.hyhqd.cn
http://mfiuTG7d.hyhqd.cn
http://CWg6jLxr.hyhqd.cn
http://I2mv51sg.hyhqd.cn
http://2BLn7cMa.hyhqd.cn
http://uuTYQP9K.hyhqd.cn
http://1iSpHwaq.hyhqd.cn
http://ssA2uh8n.hyhqd.cn
http://whoucGk7.hyhqd.cn
http://w7VBBMUU.hyhqd.cn
http://gYRridom.hyhqd.cn
http://FgKbwonj.hyhqd.cn
http://VLgwnN3T.hyhqd.cn
http://www.dtcms.com/a/382537.html

相关文章:

  • DENOISING DIFFUSION IMPLICIT MODELS
  • Gradle 安装与配置 环境配置 仓库管理 项目介绍 优缺点介绍
  • Replit CEO演讲:软件开发的未来与AI代理革命
  • LeetCode 3541.找到频率最高的元音和辅音:计数(位运算)
  • 使用Python创建本地Http服务实现与外部系统数据对接
  • Redis 线上问题排查简版手册
  • python学习之基本库/第三方库的认识和学习
  • 深度解析电动汽车绝缘材料的性能测试标准与解决方案
  • 通讯工程师专业实务-数据库、软件开发、云计算
  • 栈(Java)
  • StarRocks and Doris
  • Python进阶教程:随机数、正则表达式与异常处理
  • 【面试题】大模型高频面试题
  • UE5日期减日期
  • Redis Stream 命令
  • 微信小程序开发教程(十)
  • 弧形导轨如何提升新能源汽车的能效和续航里程?
  • 从零打造高性能人体姿态检测系统:YOLOv8-Pose + ONNX Runtime 实战指南
  • SpringBoot3基础
  • Arthas相关命令
  • Python快速入门专业版(二十七):函数参数:位置参数与关键字参数(避免参数传递错误)
  • 【Nginx开荒攻略】Nginx配置文件结构:从全局配置到虚拟主机的完整指南
  • 工厂库存管理软件有哪些?
  • Dji模拟器制作
  • 分布式文件系统元数据设计概述
  • docke笔记下篇
  • 机器学习-方差和偏差
  • 高可用集群软件——Keeepalived简介及其相关内容剖析
  • vue3项目启动流程讲解
  • 如何关闭电脑安全和防护