71

I'm trying to understand Pattern.quote using the following code:

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

produces the output:

Pattern is : \Q1252343% 8 567 hdfg gf^$545\E

What are \Q and \E here? The documentation description says :

Returns a literal pattern String for the specified String.

This method produces a String that can be used to create a Pattern that would match the string s as if it were a literal pattern.

Metacharacters or escape sequences in the input sequence will be given no special meaning.

But Pattern.quote's return type is String and not a compiled Pattern object.

Why is this method required and what are some usage examples?

Community
  • 1
  • 1
Prateek
  • 12,014
  • 12
  • 60
  • 81

6 Answers6

88

\Q means "start of literal text" (i.e. regex "open quote")
\E means "end of literal text" (i.e. regex "close quote")

Calling the Pattern.quote() method wraps the string in \Q...\E, which turns the text is into a regex literal. For example, Pattern.quote(".*") would match a dot and then an asterisk:

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

The method's purpose is to not require the programmer to have to remember the special terms \Q and \E and to add a bit of readability to the code - regex is hard enough to read already. Compare:

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

Referring to the javadoc:

Returns a literal pattern String for the specified String.

This method produces a String that can be used to create a Pattern that would match the string s as if it were a literal pattern.

Metacharacters or escape sequences in the input sequence will be given no special meaning.

Community
  • 1
  • 1
Bohemian
  • 412,405
  • 93
  • 575
  • 722
  • 9
    The correct equivalent to `someString.matches(Pattern.quote(someLiteral))` is actually `someString.matches("\\Q" + someLiteral.replace("\\E", "\\E\\\\E\\Q") + "\\E")` – kbolino May 16 '16 at 14:54
  • @kbolino Rofl. And what about replacing "\\Q"? – Andrew Oct 23 '17 at 17:12
  • @Andrew It handles that too: `"\\Q\\E".matches(Pattern.quote("\\Q\\E")) // true`. – Bohemian Oct 23 '17 at 18:17
  • Nein: "\\Q" becomes "\\Q\\Q\\E", no? – Andrew Oct 23 '17 at 18:40
  • 2
    @Andrew yes, but regex is smart enough to know how to handle that: The quoted text is everything from a `\Q` (exclusive) to the next `\E` (exclusive), which may include any number of `\Q` sequences. – Bohemian Oct 23 '17 at 20:41
20

The Pattern.quote method quotes part of a regex pattern to make regex interpret it as string literals.

Say you have some user input in your search program, and you want to regex for it. But this input may have unsafe characters so you can use

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

This method does not quote a Pattern but, as you point out, wraps a String in regex quotes.

Boris the Spider
  • 59,842
  • 6
  • 106
  • 166
10

\Q and \E, among all others, are thoroughly documented on the java.util.regex.Pattern Javadoc page. They mean "begin Quote", "End quote" and demark a region where all the chars have the literal meaning. The way to use the return of Pattern.quote is to feed it to Pattern.compile, or any other method that accepts a pattern string, such as String.split.

Marko Topolnik
  • 195,646
  • 29
  • 319
  • 436
7

If you compile the String returned by Pattern.quote, you'll get a Pattern which matches the literal string that you quoted.

\Q and \E mark the beginning and end of the quoted part of the string.

OpenSauce
  • 8,533
  • 1
  • 24
  • 29
7

Regex collides frequently with normal strings. Say I want a regex to search for a certain string that is only known at runtime. How can we be sure that the string doesn't have regex meaning eg(".*.*.*")? We quote it.

eebbesen
  • 5,070
  • 8
  • 48
  • 70
spender
  • 117,338
  • 33
  • 229
  • 351
  • Indeed, one such example is when you want to replace the first occurrence of a substring, but String.replaceFirst takes a regex, when you want to pass a literal string. – Klitos Kyriacou Apr 13 '15 at 10:15
0

This method used to make the pattern treated as a sequence of literal characters. This has the same effect as a PATTERN.LITERAL flag.

logbasex
  • 1,688
  • 1
  • 16
  • 22