Метод replaceAll () String и escape-символы

19

Линия

System.out.println("\");

выводит одну обратную косую черту ( \ ). И

System.out.println("\\");

печатает двойные обратные слеши ( \ ). Понял!

Но почему в следующем коде:

class ReplaceTest
{
    public static void main(String[] args)
    {
        String s = "hello.world";
        s = s.replaceAll("\.", "\\");
        System.out.println(s);
    }
}

- результат:

hello\world

вместо

hello\world

В конце концов, метод replaceAll() заменяет точку ( \. ) на ( \\ ).

Может кто-нибудь объяснить это?

    
задан WickeD 02.06.2012 в 22:31
источник

6 ответов

22

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

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

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

    
ответ дан Reverend Gonzo 02.06.2012 в 22:38
источник
  • , так что в основном вы говорите, что синтаксический анализатор строк сначала проанализирует «\\\\» на «\\», который парсер регулярных выражений будет далее анализировать на «\». Это оно?? –  WickeD 02.06.2012 в 22:41
  • Да, точно ... –  Reverend Gonzo 02.06.2012 в 22:44
  • Да, я немного смущен, потому что в примере в вопросе, почему синтаксический анализатор синтаксического анализа не анализировал \\. в виде \. которое регулярное выражение будет затем анализировать. –  ametren 02.06.2012 в 22:44
  • @ametren это правильно. В первой части замены это действительно \. так как он ускользает от точки, так как это имеет особое значение, так что это становится просто ». который затем заменяется на строку во втором аргументе. –  Reverend Gonzo 02.06.2012 в 22:46
  • Nevermind, просто понял, что я совершенно неправильно понял вопрос в первую очередь. –  ametren 02.06.2012 в 22:46
14

javadoc replaceAll говорит:

  

Обратите внимание, что обратная косая черта (\) и знаки доллара ($) в замене   строка может привести к тому, что результаты будут отличаться от того,   рассматривается как буквальная строка замены; см. Matcher.replaceAll. <Сильный> Использование   Matcher.quoteReplacement (java.lang.String) для подавления специальных   значение этих символов, если это необходимо.

    
ответ дан JB Nizet 02.06.2012 в 22:38
источник
  • +1 для упоминания Matcher.quoteReplacement! РЕДАКТИРОВАТЬ: удалите код (я не хочу, чтобы его отступом с мини-уценкой) –  Christophe Blin 02.10.2013 в 12:14
4

Если вам не нужно регулярное выражение для замены и просто нужно заменить точные строки, избегайте символов управления регулярным выражением перед заменой

String trickyString = "$Ha!I'm tricky|.|";
String safeToUseInReplaceAllString = Pattern.quote(trickyString);
    
ответ дан Gorky 30.09.2014 в 06:04
источник
3

Это форматированное добавление к моему комментарию

s = s.replaceAll("\.", Matcher.quoteReplacement("\"));  

БОЛЬШЕ ЧИТАЕМОГО И ЗНАЧИТЕЛЬНОГО, ЧЕМ

s = s.replaceAll("\.", "\\\");
    
ответ дан Christophe Blin 02.10.2013 в 12:20
источник
0

Обратная косая черта - это символ escape в строках Java. например обратная косая черта имеет предопределенное значение в Java. Вы должны использовать «\ \» для определения одного обратного слэша. Если вы хотите определить «\ w», вы должны использовать «\ \ w» в своем регулярном выражении. Если вы хотите использовать обратную косую черту как литерал, вы должны ввести \ \ \ \ as \ также escape-символ в регулярных выражениях.     

ответ дан David Mathias 02.06.2012 в 22:49
источник
0

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

Использование replaceAll:

s = s.replaceAll("\.", "\\\\");

Использование replace:

s = s.replaceAll(".", "\");

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

ответ дан Bogoth 13.12.2014 в 01:50
источник