String.replaceВсе одиночная обратная косая черта с двойной обратной косой чертой

Я пытаюсь преобразовать String \something\ в String \\something\\ using replaceAll , но я все время получаю всевозможные ошибки. Я думал, что это решение:

 theString.replaceAll("\\", "\\\\"); 

Но это дает следующее исключение:

 java.util.regex.PatternSyntaxException: Unexpected internal error near index 1 

String#replaceAll() интерпретирует аргумент как регулярное выражение . Параметр \ является escape-символом как в String и в regex . Вам нужно дважды уйти от него для регулярного выражения:

 string.replaceAll("\\\\", "\\\\\\\\"); 

Но для этого вам не обязательно нужно регулярное выражение, просто потому, что вам нужна точная замена по-символу, и вам здесь не нужны шаблоны. Поэтому String#replace() должно быть достаточным:

 string.replace("\\", "\\\\"); 

Обновление : согласно комментариям, вы, похоже, хотите использовать строку в контексте JavaScript. Возможно, вам лучше использовать StringEscapeUtils#escapeEcmaScript() чтобы покрыть больше символов.

Чтобы избежать replaceAll проблем, вы можете использовать replace (который принимает простую строку) вместо replaceAll (который принимает регулярное выражение). Вам все равно придется скрывать обратную косую черту, но не в диких направлениях, требуемых регулярными выражениями.

Вам нужно будет избежать обратного слэша (escaped) в первом аргументе, поскольку это регулярное выражение. Замена (второй аргумент – см. Matcher # replaceAll (String) ) также имеет особое значение обратных косых черт, поэтому вам придется заменить их на:

 theString.replaceAll("\\\\", "\\\\\\\\"); 

replaceAll(target, replacement) использует синтаксис регулярного выражения (regex) для target и частично для replacement .

Проблема заключается в том, что \ является специальным символом в регулярном выражении (например, \d для представления цифры) и в литерале строки (например, \n для создания разделителя строк или \" для представления символа двойной кавычки), и для создания символа \ нам нужно убежать с ним дополнительно \ перед этим на обоих этих уровнях.

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

  • в регулярном выражении \\
  • Строковый литерал "\\\\" (каждый \ нуждается в его дополнительном \ перед).

В случае replacement \ также является специальным, чтобы избежать другого специального символа, который равен $ . Через нотацию $x часть данных, сопоставляемая регулярным выражением, может быть доступна и повторно использована взамен, например replaceAll("(\d)", "$1$1") будет дублировать каждую цифру.

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

  • \\
  • но строковый литерал, представляющий \\ выглядит как "\\\\"

НО, так как мы хотим поставить два \ в замене, нам нужно "\\\\\\\\" там (два "\\\\" ).

 replaceAll("\\\\", "\\\\\\\\"); 

Чтобы упростить жизнь, Java предоставляет инструменты для автоматического удаления текста в target и replacement части. Итак, теперь мы можем сосредоточиться только на строках и забыть о синтаксисе regex:

 replaceAll(Pattern.quote(target), Matcher.quoteReplacement(replacement)) 

который в нашем случае может выглядеть

 replaceAll(Pattern.quote("\\"), Matcher.quoteReplacement("\\\\")) 

Или даже проще, если мы не хотим использовать regex, мы не replaceAll включать replaceAll и вместо этого replaceAll использовать replace (оба метода заменят все target s, но во втором не будет синтаксис regex). Так что вы могли бы просто написать

 theString = theString.replace("\\", "\\\\") 

Да … к тому времени, когда компилятор регулярных выражений увидит шаблон, который вы ему дали, он видит только одну обратную косую черту (поскольку лексер Java превратил двойной backwhack в один). Вам нужно заменить "\\\\" на "\\\\" , верьте или нет! Java действительно нуждается в хорошем синтаксисе строки.

  • Создание XML-файла с использованием java
  • Можете ли вы объяснить процесс подключения HttpURLConnection?
  • Управление очень повторяющимся кодом и документацией в Java
  • Генерирование Java и инициализация массива
  • Java: разница между методами setPreferredSize () и setSize () в компонентах
  • Сбор мусора по локальной переменной
  • Когда использовать абстрактный class или интерфейс?
  • Преобразование формата даты Java - получение неправильного месяца
  • Темабезопасный одноэлементный class
  • Никогда не заканчивается ответ сервера чтения с помощью jSch
  • Как управлять версиями REST API с весной?
  • Давайте будем гением компьютера.