Pattern.quote方法有什么用途?

71

我正在尝试使用以下代码来理解Pattern.quote

String pattern = Pattern.quote("1252343% 8 567 hdfg gf^$545");
System.out.println("Pattern is : "+pattern);

输出结果为:

Pattern is : \Q1252343% 8 567 hdfg gf^$545\E
这里的\Q和\E是什么?文档说明如下: 返回指定字符串的文字模式String。 该方法生成一个String,可用于创建Pattern,将匹配字符串s,就像它是一个文字模式一样。输入序列中的元字符或转义序列将不会被赋予任何特殊含义。 但Pattern.quote的返回类型是String而不是已编译的Pattern对象。 为什么需要该方法,有哪些用法示例?
6个回答

88

\Q 表示“文字起始”(即正则表达式的“开引号”)
\E 表示“文字结束”(即正则表达式的“闭引号”)

调用 Pattern.quote() 方法会将字符串包裹在 \Q...\E 中,这将使文本变为正则表达式的文字字面值。例如,Pattern.quote(".*") 将匹配一个点和一个星号:

System.out.println("foo".matches(".*")); // true
System.out.println("foo".matches(Pattern.quote(".*"))); // false
System.out.println(".*".matches(Pattern.quote(".*"))); // true

此方法的目的是不要求程序员记住特殊术语\Q\E,并为代码增加一些可读性 - 正则表达式已经很难读了。比较:

someString.matches(Pattern.quote(someLiteral));
someString.matches("\\Q" + someLiteral + "\\E"));

参考javadoc:

返回指定字符串的字面模式字符串。

此方法生成一个字符串,可用于创建模式,该模式将与字符串s匹配,就像它是字面模式一样。

输入序列中的元字符或转义序列将不会被赋予任何特殊含义。


9
someString.matches(Pattern.quote(someLiteral)) 的正确等价表达实际上是 someString.matches("\\Q" + someLiteral.replace("\\E", "\\E\\\\E\\Q") + "\\E") - kbolino
@kbolino 哈哈哈。那么替换“\Q”怎么样? - Andrew
@Andrew 它也可以处理这个问题:"\\Q\\E".matches(Pattern.quote("\\Q\\E")) // true - Bohemian
不是吗:Nein: "\Q" 变成了 "\Q\Q\E",对吧? - Andrew
2
@Andrew 是的,但正则表达式足够聪明,知道如何处理它:被引用的文本是从\Q(排除)到下一个\E(排除)的所有内容,其中可能包括任意数量的\Q序列。 - Bohemian

20

Pattern.quote方法可以将正则表达式模式的一部分引用起来,使得正则表达式将其视为字符串字面量。

假设您的搜索程序中有一些用户输入,您想要对它进行正则表达式匹配。但是这些输入可能包含不安全字符,因此您可以使用

Pattern pattern = Pattern.compile(Pattern.quote(userInput));

这种方法不会对Pattern进行引用,但是正如您指出的那样,它会将String包装在正则表达式引号中。


10

\Q\E等其他字符,在java.util.regex.Pattern Javadoc页面上进行了全面的文档说明。它们的含义是“开始引用”、“结束引用”,并标记一个区域,其中所有字符都具有字面意义。使用Pattern.quote返回的方式是将其提供给Pattern.compile或任何其他接受模式字符串的方法,如String.split


7
如果你编译由Pattern.quote返回的字符串,你会得到一个匹配你所quote的文本的Pattern\Q\E标记了被引用部分字符串的开头和结尾。

7

正则表达式经常与普通字符串发生冲突。比如我想使用一个正则表达式来搜索一个只在运行时才知道的特定字符串,我们如何确保该字符串没有正则表达式的意义,例如(".*.*.*")?我们需要将其引用起来。


实际上,一个这样的例子是当你想要替换子字符串的第一次出现时,但是String.replaceFirst需要一个正则表达式,而你想要传递一个字面字符串。 - Klitos Kyriacou

0

这种方法用于将模式视为字面字符序列。这与PATTERN.LITERAL标志具有相同的效果。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接