Java 教程
- Java - 首页
- Java - 概述
- Java - 历史
- Java - 特性
- Java 与 C++
- JVM - Java 虚拟机
- Java - JDK 与 JRE 与 JVM
- Java - Hello World 程序
- Java - 环境设置
- Java - 基本语法
- Java - 变量类型
- Java - 数据类型
- Java - 类型转换
- Java - Unicode 系统
- Java - 基本运算符
- Java - 注释
- Java - 用户输入
- Java - 日期和时间
Java 控制语句
- Java - 循环控制
- Java - 决策制定
- Java - If-else
- Java - Switch
- Java - For 循环
- Java - For-Each 循环
- Java - While 循环
- Java - do-while 循环
- Java - Break
- Java - Continue
面向对象编程
- Java - OOPs 概念
- Java - 对象和类
- Java - 类属性
- Java - 类方法
- Java - 方法
- Java - 变量作用域
- Java - 构造函数
- Java - 访问修饰符
- Java - 继承
- Java - 聚合
- Java - 多态
- Java - 重写
- Java - 方法重载
- Java - 动态绑定
- Java - 静态绑定
- Java - 实例初始化块
- Java - 抽象
- Java - 封装
- Java - 接口
- Java - 包
- Java - 内部类
- Java - 静态类
- Java - 匿名类
- Java - 单例类
- Java - 包装类
- Java - 枚举
- Java - 枚举构造函数
- Java - 枚举字符串
Java 内置类
Java 文件处理
Java 错误和异常
- Java - 异常
- Java - try-catch 块
- Java - try-with-resources
- Java - 多重 catch 块
- Java - 嵌套 try 块
- Java - Finally 块
- Java - throw 异常
- Java - 异常传播
- Java - 内置异常
- Java - 自定义异常
Java 多线程
- Java - 多线程
- Java - 线程生命周期
- Java - 创建线程
- Java - 启动线程
- Java - 线程连接
- Java - 线程命名
- Java - 线程调度器
- Java - 线程池
- Java - 主线程
- Java - 线程优先级
- Java - 守护线程
- Java - 线程组
- Java - 关闭钩子
Java 同步
Java 网络
- Java - 网络
- Java - 套接字编程
- Java - URL 处理
- Java - URL 类
- Java - URLConnection 类
- Java - HttpURLConnection 类
- Java - Socket 类
- Java - 泛型
Java 集合
Java 接口
Java 数据结构
Java 集合算法
高级 Java
- Java - 命令行参数
- Java - Lambda 表达式
- Java - 发送电子邮件
- Java - Applet 基础
- Java - Javadoc 注释
- Java - 自动装箱和拆箱
- Java - 文件不匹配方法
- Java - REPL (JShell)
- Java - 多版本 Jar 文件
- Java - 私有接口方法
- Java - 内部类菱形运算符
- Java - 多分辨率图像 API
- Java - 集合工厂方法
- Java - 模块系统
- Java - Nashorn JavaScript
- Java - Optional 类
- Java - 方法引用
- Java - 函数式接口
- Java - 默认方法
- Java - Base64 编码解码
- Java - Switch 表达式
- Java - Teeing 收集器
- Java - 微基准测试
- Java - 文本块
- Java - 动态 CDS 归档
- Java - Z 垃圾收集器 (ZGC)
- Java - 空指针异常
- Java - 打包工具
- Java - 密封类
- Java - 记录类
- Java - 隐藏类
- Java - 模式匹配
- Java - 简洁数字格式化
- Java - 垃圾回收
- Java - JIT 编译器
Java 杂项
- Java - 递归
- Java - 正则表达式
- Java - 序列化
- Java - 字符串
- Java - Process API 增强
- Java - Stream API 增强
- Java - 增强 @Deprecated 注解
- Java - CompletableFuture API 增强
- Java - 流
- Java - 日期时间 API
- Java 8 - 新特性
- Java 9 - 新特性
- Java 10 - 新特性
- Java 11 - 新特性
- Java 12 - 新特性
- Java 13 - 新特性
- Java 14 - 新特性
- Java 15 - 新特性
- Java 16 - 新特性
Java API 和框架
Java 类参考
- Java - Scanner
- Java - 数组
- Java - 字符串
- Java - Date
- Java - ArrayList
- Java - Vector
- Java - Stack
- Java - PriorityQueue
- Java - LinkedList
- Java - ArrayDeque
- Java - HashMap
- Java - LinkedHashMap
- Java - WeakHashMap
- Java - EnumMap
- Java - TreeMap
- Java - IdentityHashMap
- Java - HashSet
- Java - EnumSet
- Java - LinkedHashSet
- Java - TreeSet
- Java - BitSet
- Java - Dictionary
- Java - Hashtable
- Java - Properties
- Java - Collection
- Java - Array
Java 有用资源
Java - 正则表达式
Java 提供了 java.util.regex 包用于使用正则表达式进行模式匹配。Java 正则表达式与 Perl 编程语言非常相似,并且非常容易学习。
Java 中的正则表达式
正则表达式是用于匹配或查找其他字符串或字符串集的特殊字符序列,使用包含在模式中的专门语法。它们可用于搜索、编辑或处理文本和数据。
Java 正则表达式 (Regex) 类
java.util.regex 包主要包含以下三个类 -
Pattern 类 - Pattern 对象是正则表达式的编译表示形式。Pattern 类没有提供公共构造函数。要创建模式,您必须首先调用其公共静态 compile() 方法之一,然后该方法将返回一个 Pattern 对象。这些方法接受正则表达式作为第一个参数。
Matcher 类 - Matcher 对象是解释模式并对输入字符串执行匹配操作的引擎。与 Pattern 类一样,Matcher 没有定义公共构造函数。您可以通过在 Pattern 对象上调用 matcher() 方法来获取 Matcher 对象。
PatternSyntaxException - PatternSyntaxException 对象是一个未经检查的异常,表示正则表达式模式中的语法错误。
正则表达式中的捕获组
捕获组是一种将多个字符视为单个单元的方法。它们是通过将要分组的字符放在一组括号内创建的。例如,正则表达式 (dog) 创建了一个包含字母“d”、“o”和“g”的单个组。
捕获组的编号是通过从左到右计算其开括号来确定的。例如,在表达式 ((A)(B(C))) 中,有四个这样的组 -
- ((A)(B(C)))
- (A)
- (B(C))
- (C)
要找出表达式中存在多少个组,请在 matcher 对象上调用 groupCount 方法。groupCount 方法返回一个 int,表示匹配器模式中存在的捕获组的数量。
还有一个特殊的组,组 0,它始终表示整个表达式。groupCount 报告的总数不包括此组。
示例
以下示例说明如何从给定的字母数字字符串中查找数字字符串 -
import java.util.regex.Matcher; import java.util.regex.Pattern; public class RegexMatches { public static void main( String args[] ) { // String to be scanned to find the pattern. String line = "This order was placed for QT3000! OK?"; String pattern = "(.*)(\\d+)(.*)"; // Create a Pattern object Pattern r = Pattern.compile(pattern); // Now create matcher object. Matcher m = r.matcher(line); if (m.find( )) { System.out.println("Found value: " + m.group(0) ); System.out.println("Found value: " + m.group(1) ); System.out.println("Found value: " + m.group(2) ); }else { System.out.println("NO MATCH"); } } }
输出
Found value: This order was placed for QT3000! OK? Found value: This order was placed for QT300 Found value: 0
正则表达式语法
以下是 Java 中所有可用正则表达式元字符语法的列表 -
子表达式 | 匹配 |
---|---|
^ | 匹配行首。 |
$ | 匹配行尾。 |
. | 匹配任何单个字符,但换行符除外。使用 m 选项允许它匹配换行符。 |
[...] | 匹配括号中任何单个字符。 |
[^...] | 匹配括号中任何单个字符。 |
\A | 整个字符串的开头。 |
\z | 整个字符串的结尾。 |
\Z | 整个字符串的结尾,除了允许的最终行终止符。 |
re* | 匹配前一个表达式的 0 个或多个出现。 |
re+ | 匹配前一个表达式的 1 个或多个出现。 |
re? | 匹配前一个表达式的 0 个或 1 个出现。 |
re{ n} | 精确匹配前一个表达式的 n 个出现。 |
re{ n,} | 匹配前一个表达式的 n 个或更多出现。 |
re{ n, m} | 至少匹配前一个表达式的 n 个出现,最多 m 个出现。 |
a| b | 匹配 a 或 b。 |
(re) | 对正则表达式进行分组并记住匹配的文本。 |
(?: re) | 对正则表达式进行分组,但不记住匹配的文本。 |
(?> re) | 匹配不回溯的独立模式。 |
\w | 匹配单词字符。 |
\W | 匹配非单词字符。 |
\s | 匹配空白字符。等效于 [\t\n\r\f]。 |
\S | 匹配非空白字符。 |
\d | 匹配数字。等效于 [0-9]。 |
\D | 匹配非数字。 |
\A | 匹配字符串的开头。 |
\Z | 匹配字符串的结尾。如果存在换行符,则匹配换行符之前的字符。 |
\z | 匹配字符串的结尾。 |
\G | 匹配上次匹配结束的位置。 |
\n | 反向引用捕获组编号为“n”的组。 |
\b | 在括号外部匹配单词边界。在括号内部匹配退格键 (0x08)。 |
\B | 匹配非单词边界。 |
\n, \t, 等。 | 匹配换行符、回车符、制表符等。 |
\Q | 转义(引用)直到 \E 之前的所有字符。 |
\E | 结束以 \Q 开始的引用。 |
正则表达式 - Matcher 类方法
以下是有用的实例方法列表:
索引方法
索引方法提供有用的索引值,精确地显示匹配在输入字符串中的位置:
序号 | 方法及描述 |
---|---|
1 | public int start() 返回上一次匹配的起始索引。 |
2 | public int start(int group) 返回在上一次匹配操作期间由给定组捕获的子序列的起始索引。 |
3 | public int end() 返回匹配到的最后一个字符之后的偏移量。 |
4 | public int end(int group) 返回在上一次匹配操作期间由给定组捕获的子序列的最后一个字符之后的偏移量。 |
研究方法
研究方法检查输入字符串并返回一个布尔值,指示是否找到模式:
序号 | 方法及描述 |
---|---|
1 | public boolean lookingAt() 尝试从区域的开头开始,将输入序列与模式进行匹配。 |
2 | public boolean find() 尝试查找输入序列中与模式匹配的下一个子序列。 |
3 | public boolean find(int start) 重置此匹配器,然后尝试查找输入序列中与模式匹配的下一个子序列,从指定的索引开始。 |
4 | public boolean matches() 尝试将整个区域与模式进行匹配。 |
正则表达式 - 替换方法
替换方法是用于替换输入字符串中文本的有用方法:
序号 | 方法及描述 |
---|---|
1 | public Matcher appendReplacement(StringBuffer sb, String replacement) 实现一个非终端的追加和替换步骤。 |
2 | public StringBuffer appendTail(StringBuffer sb) 实现一个终端的追加和替换步骤。 |
3 | public String replaceAll(String replacement) 将输入序列中与模式匹配的每个子序列替换为给定的替换字符串。 |
4 | public String replaceFirst(String replacement) 将输入序列中与模式匹配的第一个子序列替换为给定的替换字符串。 |
5 | public static String quoteReplacement(String s) 返回指定字符串的文字替换字符串。此方法生成一个字符串,该字符串将在 Matcher 类的 appendReplacement 方法中用作文字替换s。 |
start 和 end 方法
以下示例计算单词“cat”在输入字符串中出现的次数:
示例
import java.util.regex.Matcher; import java.util.regex.Pattern; public class RegexMatches { private static final String REGEX = "\\bcat\\b"; private static final String INPUT = "cat cat cat cattie cat"; public static void main( String args[] ) { Pattern p = Pattern.compile(REGEX); Matcher m = p.matcher(INPUT); // get a matcher object int count = 0; while(m.find()) { count++; System.out.println("Match number "+count); System.out.println("start(): "+m.start()); System.out.println("end(): "+m.end()); } } }
输出
Match number 1 start(): 0 end(): 3 Match number 2 start(): 4 end(): 7 Match number 3 start(): 8 end(): 11 Match number 4 start(): 19 end(): 22
您可以看到,此示例使用单词边界来确保字母“c” “a” “t”不仅仅是较长单词中的子字符串。它还提供了一些关于匹配发生在输入字符串中的哪个位置的有用信息。
start 方法返回在上一次匹配操作期间由给定组捕获的子序列的起始索引,而 end 返回匹配到的最后一个字符的索引加一。
matches() 和 lookingAt() 方法
matches 和 lookingAt 方法都尝试将输入序列与模式进行匹配。但是,区别在于 matches 要求匹配整个输入序列,而 lookingAt 则不需要。
两种方法始终从输入字符串的开头开始。以下示例解释了其功能:
示例
import java.util.regex.Matcher; import java.util.regex.Pattern; public class RegexMatches { private static final String REGEX = "foo"; private static final String INPUT = "fooooooooooooooooo"; private static Pattern pattern; private static Matcher matcher; public static void main( String args[] ) { pattern = Pattern.compile(REGEX); matcher = pattern.matcher(INPUT); System.out.println("Current REGEX is: "+REGEX); System.out.println("Current INPUT is: "+INPUT); System.out.println("lookingAt(): "+matcher.lookingAt()); System.out.println("matches(): "+matcher.matches()); } }
输出
Current REGEX is: foo Current INPUT is: fooooooooooooooooo lookingAt(): true matches(): false
replaceFirst() 和 replaceAll() 方法
replaceFirst 和 replaceAll 方法替换与给定正则表达式匹配的文本。顾名思义,replaceFirst 替换第一个出现的匹配项,而 replaceAll 替换所有出现的匹配项。
以下示例解释了其功能:
示例
import java.util.regex.Matcher; import java.util.regex.Pattern; public class RegexMatches { private static String REGEX = "dog"; private static String INPUT = "The dog says meow. " + "All dogs say meow."; private static String REPLACE = "cat"; public static void main(String[] args) { Pattern p = Pattern.compile(REGEX); // get a matcher object Matcher m = p.matcher(INPUT); INPUT = m.replaceAll(REPLACE); System.out.println(INPUT); } }
输出
The cat says meow. All cats say meow.
appendReplacement() 和 appendTail() 方法
Matcher 类还为文本替换提供 appendReplacement 和 appendTail 方法。
以下示例解释了其功能:
示例
import java.util.regex.Matcher; import java.util.regex.Pattern; public class RegexMatches { private static String REGEX = "a*b"; private static String INPUT = "aabfooaabfooabfoob"; private static String REPLACE = "-"; public static void main(String[] args) { Pattern p = Pattern.compile(REGEX); // get a matcher object Matcher m = p.matcher(INPUT); StringBuffer sb = new StringBuffer(); while(m.find()) { m.appendReplacement(sb, REPLACE); } m.appendTail(sb); System.out.println(sb.toString()); } }
输出
-foo-foo-foo-
正则表达式 - PatternSyntaxException 类方法
PatternSyntaxException 是一个未经检查的异常,表示正则表达式模式中的语法错误。PatternSyntaxException 类提供以下方法来帮助您确定问题所在:
序号 | 方法及描述 |
---|---|
1 | public String getDescription() 检索错误的描述。 |
2 | public int getIndex() 检索错误索引。 |
3 | public String getPattern() 检索错误的正则表达式模式。 |
4 | public String getMessage() 返回一个多行字符串,其中包含语法错误及其索引的描述、错误的正则表达式模式以及模式中错误索引的可视指示。 |