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 上找到。