Восемь обратной косой черты требуется для замены одиночной обратной косой черты? - PullRequest
5 голосов
/ 14 октября 2011

Это вопрос "что, черт возьми, здесь происходит".На самом деле мне не нужно решение.

Мне пришлось заменить все одиночные обратные косые черты в строке на двойные обратные косые черты.Это то, что я в итоге сделал ...

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

... где strRootDirectory - это java.lang.String выше.

Теперь я понимаю четыре обратных слеша для первого аргумента: regex ожидает две обратных косых черты, чтобы указать одну буквальную обратную косую черту, а java хочет, чтобы они удвоились.Это нормально.

НО, что, черт возьми, происходит с восемью обратными слешами для второго аргумента?Разве замещающая строка не должна быть литеральной (я имею в виду не регулярное выражение)?Я ожидал, что во втором аргументе понадобится четыре обратных слеша, чтобы представить два обратных слеша.

Ответы [ 6 ]

8 голосов
/ 14 октября 2011

Второй аргумент - не строка регулярного выражения, а строка замены регулярного выражения, в которой обратный слеш также имеет особое значение (он используется для экранирования специального символа $, используемого для интерполяции переменных, и также раньше убегал сам).

Из API:

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

- http://download.oracle.com/javase/6/docs/api/java/lang/String.html#replaceAll(...)

6 голосов
/ 14 октября 2011

Проще, если вы используете replace("\\","\\\\") (String.replace принимает буквенные строки и более эффективно, когда все буквально)

или вы можете убедиться в правильности с помощью функций Pattern.quote и Matcher.quoteReplacement

2 голосов
/ 14 октября 2011

"\\\\\\\\" приводит к представлению в памяти строки с 4 обратными слешами: \\\\. Хотя вторая строка не является строкой регулярного выражения, обратные слеши и знаки доллара по-прежнему являются специальными символами, поэтому их необходимо экранировать.

1 голос
/ 10 августа 2013

Как поклонник того, чтобы не вдаваться в подробные объяснения регулярных выражений ... Я понял из основного поста ответа Барта Кирса выше:

System.out.println( "line1: "+"hello\\\\world" );
System.out.println( "line2: "+"hello\\\\world".replaceAll("\\\\\\\\", Matcher.quoteReplacement("\\") ) );

распечатывает

line1: hello\\world
line2: hello\world

Надеюсь, это поможет ...

1 голос
/ 14 октября 2011

Да, это становится волосатым, когда вам нужно делать подобные вещи, не так ли.

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

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

Это составляет 8.

1 голос
/ 14 октября 2011

Согласно справочному материалу Java, метод replaceAll также интерпретирует обратную косую черту в строке замены как escape-символы. Их можно использовать для экранирования знака доллара, который может ссылаться на совпавшие выражения для повторного использования в строке замены. Естественно, если вы хотите удвоить число обратных слешей, и оба параметра обрабатывают обратную косую черту как escape-символ, вам нужно вдвое больше обратных слешей в строке замены.

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