Как заменить пространство именно с помощью & ldquo; \\\\ s + & rdquo; [Дубликат]

В дополнение к уже выбранному ответу (и различным информационным сообщениям здесь) я настоятельно рекомендую захватить копию Head First Design Patterns . Это очень простое чтение и ответит на ваш вопрос напрямую, объясните, почему это важно, и покажите вам много шаблонов программирования, которые вы можете использовать, чтобы использовать этот принцип (и другие).

102
задан BalusC 13 August 2015 в 08:09
поделиться

5 ответов

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

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

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

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

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

176
ответ дан BalusC 21 August 2018 в 10:33
поделиться
  • 1
    Фактически, он используется в JavaScript AST, который должен быть преобразован обратно в исходный код. Ваше решение работает. Благодаря! – Frank Groeneveld 9 November 2009 в 16:47
  • 2
    Если вы все равно хотите использовать String#replaceAll(), вы можете процитировать заменяющую строку с помощью Matcher # quoteReplacement () : theString.replaceAll("\\", Matcher.quoteReplacement("\\\\")); – ph.dev 12 November 2015 в 18:06
  • 3

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

13
ответ дан Fabian Steeg 21 August 2018 в 10:33
поделиться

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

4
ответ дан Jonathan Feinberg 21 August 2018 в 10:33
поделиться

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

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

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

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

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

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

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

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

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

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

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

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

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

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

theString = theString.replace("\\", "\\\\")
7
ответ дан Pshemo 21 August 2018 в 10:33
поделиться

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

theString.replaceAll("\\\\", "\\\\\\\\");
7
ответ дан sfussenegger 21 August 2018 в 10:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: