Экранирование строки из анализа регулярного выражения в Java - PullRequest
13 голосов
/ 03 октября 2008

В Java предположим, что у меня есть строковая переменная S, и я хочу найти ее в другой строковой переменной T, например:

   if (T.matches(S)) ...

(примечание: приведенная выше строка была T.contains (), пока в нескольких сообщениях не указывалось, что этот метод не использует регулярные выражения. Мое плохое.)

Но теперь предположим, что в S могут быть неприятные символы. Например, пусть S = "[hi". Левая квадратная скобка приведет к сбою регулярного выражения. Есть ли функция, которую я могу вызвать, чтобы избежать S, чтобы этого не произошло? В этом конкретном случае я бы хотел, чтобы оно было преобразовано в "\ [hi".

Ответы [ 6 ]

20 голосов
/ 04 октября 2008

String.contains не использует регулярные выражения, поэтому в этом случае проблем нет.

Если требуется регулярное выражение, вместо отклонения строк со специальными символами регулярного выражения, используйте java.util.regex.Pattern.quote, чтобы экранировать их.

12 голосов
/ 04 октября 2008

Как сказал Том Хотин , вам нужно процитировать образец. Вы можете сделать это двумя способами (редактировать: фактически тремя способами, как указано в @ диастрофизм ):

  1. Окружите строку "\ Q" и "\ E", например:

    if (T.matches("\\Q" + S + "\\E"))
    
  2. Используйте взамен Pattern . Код будет выглядеть примерно так:

    Pattern sPattern = Pattern.compile(S, Pattern.LITERAL);
    if (sPattern.matcher(T).matches()) { /* do something */ }
    

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

Обратите внимание, что если вы используете регулярные выражения для проверки, находится ли строка внутри большей строки, вы должны поставить. * В начале и конце выражения. Но это не сработает, если вы цитируете шаблон, поскольку тогда он будет искать реальные точки. Итак, вы абсолютно уверены, что хотите использовать регулярные выражения?

6 голосов
/ 04 октября 2008

Попробуйте Pattern.quote (String) . Это исправит все, что имеет особое значение в строке.

2 голосов
/ 04 октября 2008

Есть какая-то конкретная причина не использовать вместо этого String.indexOf ()? Таким образом, он всегда будет интерпретироваться как обычная строка, а не как регулярное выражение.

0 голосов
/ 04 октября 2008

T.contains () (согласно javadoc: http://java.sun.com/javase/6/docs/api/java/lang/String.html) не использует регулярные выражения. Содержит делегаты () только для indexOf ().

Итак, здесь НЕТ регулярных выражений. Вы думали о каком-нибудь другом методе String?

0 голосов
/ 04 октября 2008

Regex использует символ обратной косой черты '\' для экранирования литерала. Учитывая, что java также использует символ обратной косой черты, вам необходимо использовать двойную косую черту, например:

   String S = "\\[hi"

Это станет строкой:

  \[hi

, который будет передан в регулярное выражение.

Или если вы заботитесь только о буквальной строке и не нуждаетесь в регулярном выражении, вы можете сделать следующее:

if (T.indexOf("[hi") != -1)  {
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...