Java, регулярное выражение, необходимо экранировать обратную косую черту в регулярных выражениях - PullRequest
11 голосов
/ 02 февраля 2012

Со ссылкой на вопрос ниже - String.replaceВсе одиночные обратные косые черты с двойными обратными косыми чертами

Я написал тестовую программу и обнаружил, что результат верен в обоих случаях, независимо от того, ухожу ли яобратная косая черта или нет.Это может быть потому, что - \ t является распознанной escape-последовательностью Java String.(Попробуйте \ s, и он будет жаловаться).- \ t берется как буквальная вкладка в регулярном выражении.Я несколько не уверен в причинах.

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

Я бы хотел узнать ваше мнение.

public class TestDeleteMe {

  public static void main(String args[]) {
    System.out.println(System.currentTimeMillis());

    String str1 = "a    b"; //tab between a and b 

    //pattern - a and b with any number of spaces or tabs between 
    System.out.println("matches = " + str1.matches("^a[ \\t]*b$")); 
    System.out.println("matches = " + str1.matches("^a[ \t]*b$")); 
  }
}

Ответы [ 4 ]

9 голосов
/ 02 февраля 2012

Существует две интерпретации escape-последовательностей: сначала компилятором Java, а затем механизмом регулярных выражений. Когда компилятор Java видит две косые черты, он заменяет их одной косой чертой. Когда после косой черты t, Java заменяет ее на вкладку; когда после двойной косой черты стоит t, Java оставляет ее в покое. Однако, поскольку две косые черты были заменены одной косой чертой, механизм регулярных выражений видит \t и интерпретирует его как табуляцию.

Я думаю, что более разумно позволить регулярному выражению интерпретировать \t как вкладку (то есть писать "\\t" в Java), потому что оно позволяет вам видеть выражение в его предполагаемой форме во время отладки, ведения журнала и т. Д. Если вы преобразуете Pattern с \t в строку, вы увидите символ табуляции в середине вашего регулярного выражения и можете спутать его с другими пробелами. Шаблоны с \\t не имеют этой проблемы: они покажут вам \t с одной косой чертой, точно указав тип пробела, который им соответствует.

6 голосов
/ 02 февраля 2012

Да, есть общее руководство по экранированию: Escape-последовательности в вашем исходном коде Java заменяются компилятором Java (или каким-то образом препроцессором).Компилятор будет жаловаться на любые escape-последовательности, которые ему не известны, например, \s.Когда вы пишете строковый литерал для шаблона RegEx, компилятор обработает этот литерал как обычно и заменит все escape-последовательности соответствующим символом.Затем, когда программа выполняется, класс Pattern компилирует входную строку, то есть он будет оценивать escape-последовательности в другой раз.Класс Pattern знает \s как класс символов и поэтому сможет компилировать шаблон, содержащий этот класс.Однако вам нужно экранировать \s из компилятора Java, который не знает этой escape-последовательности.Для этого вы избегаете обратной косой черты, в результате чего получается \\s.

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

6 голосов
/ 02 февраля 2012

Первая форма \\t будет расширена до символа табуляции с помощью класса шаблона.

Вторая форма \t будет расширена до символа табуляции с помощью Java перед построением шаблона.

В конце концов, вы получаете символ табуляции в любом случае.

1 голос
/ 27 сентября 2013

С помощью org.apache.commons.lang3.StringEscapeUtils.unescapeJava (...) вы можете избежать большинства распространенных символов spl.chars, а также символов Unicode (преобразует кодировку Unicode в читаемый обычный символ)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...