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