Экранирование строки из получения регулярных выражений в Java
В Java предположим, что у меня есть строковая переменная S, и я хочу искать ее внутри другой строки T, например:
if (T.matches(S)) ...
(примечание: вышеприведенная строка была T.contains(), пока несколько сообщений не указали, что этот метод не использует регулярные выражения. Мой плохой.)
Но теперь предположим, что S может иметь в себе сомнительные символы. Например, пусть S = "[hi". Левая квадратная скобка приведет к сбою регулярного выражения. Есть ли функция, которую я могу вызвать для выхода S, чтобы этого не произошло? В этом конкретном случае я хотел бы, чтобы он был преобразован в "\ [hi".
Ответы
Ответ 1
String.contains не использует регулярное выражение, поэтому в этом случае нет проблемы.
Если требуется регулярное выражение, вместо того чтобы отклонять строки с специальными символами регулярных выражений, используйте java.util.regex.Pattern.quote, чтобы избежать их.
Ответ 2
Как сказал Tom Hawtin, вам нужно процитировать шаблон. Вы можете сделать это двумя способами (отредактируйте: на самом деле три способа, как указано @диастрофизмом):
-
Окружайте строку "\ Q" и "\ E", например:
if (T.matches("\\Q" + S + "\\E"))
-
Используйте Pattern. Код будет примерно таким:
Pattern sPattern = Pattern.compile(S, Pattern.LITERAL);
if (sPattern.matcher(T).matches()) { /* do something */ }
Таким образом, вы можете кэшировать скомпилированный шаблон и повторно использовать его. Если вы используете одно и то же регулярное выражение более одного раза, вы почти наверняка захотите сделать это таким образом.
Обратите внимание: если вы используете регулярные выражения для проверки того, находится ли строка внутри большей строки, вы должны поместить. * в начале и в конце выражения. Но это не сработает, если вы цитируете шаблон, так как он будет искать фактические точки. Итак, вы абсолютно уверены, что хотите использовать регулярные выражения?
Ответ 3
Попробуйте Pattern.quote(String). Он исправит все, что имеет особое значение в строке.
Ответ 4
Любая конкретная причина не использовать String.indexOf() вместо этого? Таким образом, он всегда будет интерпретироваться как регулярная строка, а не регулярное выражение.
Ответ 5
Regex использует символ обратной косой черты '\' для выхода из литерала. Учитывая, что java также использует символ обратной косой черты, вам нужно использовать двойной bashslash, например:
String S = "\\[hi"
Это станет строкой:
\[hi
который будет передан в регулярное выражение.
Или, если вы заботитесь только о литеральной строке и не нуждаетесь в регулярном выражении, вы можете сделать следующее:
if (T.indexOf("[hi") != -1) {
Ответ 6
T.contains() (согласно javadoc: http://java.sun.com/javase/6/docs/api/java/lang/String.html) не использует регулярные выражения. содержит() делегатов только для indexOf().
Итак, здесь нет никаких регулярных выражений. Вы думали о другом методе String?