1. 简介

正则表达式是 Java 中处理文本匹配的强大工具,通过 java.util.regex 包提供支持。它们可以精确匹配文本中的特定字符、单词或短语。在 Java 中,\z\Z$ 是三种常见的正则表达式锚点,用于匹配字符串的结尾。

本文将深入分析这三种锚点的核心差异、工作原理及适用场景。

2. 正则表达式锚点对比:\z vs \Z vs $

锚点是正则表达式中用于指定匹配位置的字符序列。虽然 \z\Z$ 都能匹配字符串结尾,但在处理行终止符(如换行符)时行为迥异:

\z 锚点
匹配字符串的绝对结尾,无视行终止符的存在。适用于需要确保匹配模式后无任何额外文本的场景。

⚠️ \Z 锚点
匹配字符串结尾或行结尾(当字符串以行终止符结束时)。适用于多行文本中匹配每行结尾的场景。

$ 锚点
功能等同于 \z,匹配字符串结尾且忽略行终止符。在大多数场景下可视为 \z 的简化形式。

3. 实战场景解析

3.1 \z 锚点的典型应用

信用卡号验证
需要严格确保卡号后无多余字符:

@Test
public void givenCreditCardNumber_thenReturnIfMatched() {
    String creditCardNumber = "1234567890123456";
    String pattern = "\\d{16}\\z";
    Assertions.assertTrue(Pattern.compile(pattern).matcher(creditCardNumber).find());
}

该测试用例验证信用卡号必须精确包含16位数字\z 确保匹配后无任何附加字符。

日志文件解析
需匹配单行结尾且避免跨行干扰:

@Test
public void givenLogOutput_thenReturnIfMatched() {
    String logLine = "2022-05-01 14:30:00,123 INFO Some log message";
    String pattern = ".*message\\z";
    Assertions.assertTrue(Pattern.compile(pattern).matcher(logLine).find());
}

即使日志行以换行符结尾,\z 仍能确保仅匹配当前行末尾的 "message"。

3.2 \Z 锚点的典型应用

邮件正文匹配
需匹配正文结尾并忽略签名部分:

@Test
public void givenEmailMessage_thenReturnIfMatched() {
    String myMessage = "Hello HR, I hope i can write to Baeldung\n";
    String pattern = ".*Baeldung\\Z";
    Assertions.assertTrue(Pattern.compile(pattern).matcher(myMessage).find());
}

\Z 允许匹配以 "Baeldung" 结尾的文本,即使其后存在换行符。

文件扩展名验证
需严格匹配文件名末尾的扩展名:

@Test
public void givenFileExtension_thenReturnIfMatched() {
    String fileName = "image.jpeg\n";
    String pattern = ".*\\.jpeg\\Z";
    Assertions.assertTrue(Pattern.compile(pattern).matcher(fileName).find());
}

该测试验证文件名必须以 .jpeg 结尾,\Z 确保即使文件名后跟换行符也能正确匹配。

3.3 $ 锚点的典型应用

URL 接口验证
需精确匹配 URL 末尾的接口路径:

@Test
public void givenURL_thenReturnIfMatched() {
    String url = "https://www.example.com/api/endpoint\n";
    String pattern = ".*/endpoint$";
    Assertions.assertTrue(Pattern.compile(pattern).matcher(url).find());
}

$ 确保 /endpoint 出现在 URL 末尾,忽略后续的换行符。

句子标点校验
需验证句子是否以标点符号结尾:

@Test
public void givenSentence_thenReturnIfMatched() {
    String sentence = "Hello, how are you?";
    String pattern = ".*[.?!]$";
    Assertions.assertTrue(Pattern.compile(pattern).matcher(sentence).find());
}

该模式检查句子必须以句号、问号或感叹号结尾,$ 确保匹配发生在字符串末尾。

4. 总结

正则表达式锚点在 Java 文本处理中至关重要:

  • \z:匹配绝对字符串结尾,无视行终止符
  • \Z:匹配字符串结尾或行结尾(含行终止符)
  • $:功能等同于 \z,匹配字符串结尾

掌握三者的核心差异能显著提升正则表达式的精确性。根据实际场景选择合适的锚点,可避免不必要的匹配错误,提升代码健壮性。

完整示例代码请查阅 GitHub 仓库


原始标题:Regular Expression: \z vs \Z Anchors in Java