1. 概述

在 Java 中使用正则表达式时,有时我们需要 以文字形式匹配正则表达式模式 - 而不处理这些序列中存在的任何 元字符

在这个快速教程中,让我们看看如何手动转义正则表达式中的元字符以及使用 Java 提供的 Pattern.quote() 方法。

2. 不转义元字符

让我们考虑一个包含美元金额列表的字符串:

String dollarAmounts = "$100.25, $100.50, $150.50, $100.50, $100.75";

现在,假设我们需要搜索其中出现的特定金额的美元。让我们相应地初始化正则表达式模式字符串:

String patternStr = "$100.50";

首先,让我们看看 如果我们执行正则表达式搜索而不转义任何元字符会发生什么

public void whenMetacharactersNotEscaped_thenNoMatchesFound() {
    Pattern pattern = Pattern.compile(patternStr);
    Matcher matcher = pattern.matcher(dollarAmounts);

    int matches = 0;
    while (matcher.find()) {
        matches++;
    }

    assertEquals(0, matches);
}

正如我们所看到的,匹配器在我们的 DollarAmounts 字符串中甚至 找不到 $150.50 的一次出现。这只是由于 以美元符号开头的 patternStr 恰好是 指定行结束的正则表达式元字符

正如您可能应该猜到的那样,我们在所有正则表达式元字符上都会面临同样的问题。我们将无法搜索包含指数(如“ 5^3 ”)的插入符(^)的数学语句,或使用反斜杠(\)的文本(如“ users\bob ”)。

3. 手动忽略元字符

其次,在执行搜索之前,让我们 转义正则表达式中的元字符

public void whenMetacharactersManuallyEscaped_thenMatchingSuccessful() {
    String metaEscapedPatternStr = "\\Q" + patternStr + "\\E";
    Pattern pattern = Pattern.compile(metaEscapedPatternStr);
    Matcher matcher = pattern.matcher(dollarAmounts);

    int matches = 0;
    while (matcher.find()) {
        matches++;
    }

    assertEquals(2, matches);
}

这一次,我们已经 成功地进行了搜索 ;但这并不是理想的解决方案,原因如下:

  • 在转义 元字符时执行字符串连接 ,这会使代码更难以理解。
  • 由于添加了硬编码值 ,代码不太干净

4.使用 Pattern.quote()

最后,让我们看看在正则表达式中忽略元字符的 最简单、最干净的方法

Java 在其 Pattern 类中提供了 quote() 方法 来检索字符串的文字模式:

public void whenMetacharactersEscapedUsingPatternQuote_thenMatchingSuccessful() {
    String literalPatternStr = Pattern.quote(patternStr);
    Pattern pattern = Pattern.compile(literalPatternStr);
    Matcher matcher = pattern.matcher(dollarAmounts);

    int matches = 0;
    while (matcher.find()) {
        matches++;
    }

    assertEquals(2, matches);
}

5. 结论

在本文中,我们研究了如何处理文字形式的正则表达式模式。

我们看到了不转义正则表达式元字符如何无法提供预期结果,以及如何使用 Pattern.quote() 方法手动执行正则表达式模式内的转义元字符。

此处使用的所有代码示例的完整源代码可以在 GitHub 上找到。