Для чего используется метод Pattern.quote?

Я пытаюсь понять 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.

Этот метод создает String, который можно использовать для создания Pattern, который будет соответствовать строке s, как если бы это был буквенный шаблон.

Метасимволы или управляющие последовательности во входной последовательности не будут иметь специального значения.

Но возвращаемый тип Pattern.quoteString, а не скомпилированный объект Pattern.

Зачем нужен этот метод и каковы примеры его использования?


person Prateek    schedule 14.03.2013    source источник


Ответы (6)


\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, как если бы это был буквальный шаблон.

Метасимволы или управляющие последовательности во входной последовательности не будут иметь специального значения.

person Bohemian♦    schedule 14.03.2013
comment
Правильный эквивалент someString.matches(Pattern.quote(someLiteral)) на самом деле someString.matches("\\Q" + someLiteral.replace("\\E", "\\E\\\\E\\Q") + "\\E") - person kbolino; 16.05.2016
comment
@kbolino Рофл. А как насчет замены \\Q? - person Andrew; 23.10.2017
comment
@Andrew Это тоже справляется: "\\Q\\E".matches(Pattern.quote("\\Q\\E")) // true. - person Bohemian♦; 23.10.2017
comment
Nein: \\Q становится \\Q\\Q\\E, нет? - person Andrew; 23.10.2017
comment
@Эндрю, да, но регулярное выражение достаточно умно, чтобы знать, как с этим справиться: цитируемый текст - это все, от \Q (исключительное) до следующего \E (исключительное), которое может включать любое количество последовательностей \Q. - person Bohemian♦; 23.10.2017

Метод Pattern.quote заключает в кавычки часть шаблона регулярного выражения, чтобы регулярное выражение интерпретировало его как строковые литералы.

Скажем, у вас есть пользовательский ввод в вашей программе поиска, и вы хотите использовать для него регулярное выражение. Но этот ввод может содержать небезопасные символы, поэтому вы можете использовать

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

Этот метод не заключает в кавычки Pattern, но, как вы указываете, заключает String в кавычки регулярного выражения.

person Boris the Spider    schedule 14.03.2013

\Q и \E, среди прочего, тщательно задокументированы в java.util. .regex.Pattern Страница Javadoc. Они означают «начало Quote», «End цитата» и отмечают область, где все символы имеют буквальное значение. Способ использования возврата Pattern.quote состоит в том, чтобы передать его Pattern.compile или любому другому методу, который принимает строку шаблона, например String.split.

person Marko Topolnik    schedule 14.03.2013

Если вы скомпилируете строку, возвращаемую Pattern.quote, вы получите Pattern, которая соответствует литеральной строке, которую вы quoted.

\Q и \E отмечают начало и конец заключенной в кавычки части строки.

person OpenSauce    schedule 14.03.2013

Regex часто сталкивается с обычными строками. Скажем, я хочу, чтобы регулярное выражение искало определенную строку, которая известна только во время выполнения. Как мы можем быть уверены, что строка не имеет значения регулярного выражения, например (".*.*.*")? Мы цитируем его.

person spender    schedule 14.03.2013
comment
Действительно, одним из таких примеров является ситуация, когда вы хотите заменить первое вхождение подстроки, но String.replaceFirst принимает регулярное выражение, когда вы хотите передать литеральную строку. - person Klitos Kyriacou; 13.04.2015

Этот метод используется для обработки шаблона как последовательности буквенных символов. Имеет тот же эффект, что и флаг PATTERN.LITERAL.

person logbasex    schedule 02.04.2020