Java: заменить все 'в строке на \'

Мне нужно экранировать все кавычки (') в строке, чтобы она стала \'

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

я пытаюсь с

String s = "You'll be totally awesome, I'm really terrible";
String shouldBecome = "You\'ll be totally awesome, I\'m really terrible";
s = s.replaceAll("'","\\'"); // Doesn't do anything
s = s.replaceAll("\'","\\'"); // Doesn't do anything
s = s.replaceAll("\\'","\\'"); // Doesn't do anything

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

Спасибо,

Иван


person Iwan Eising    schedule 12.12.2013    source источник
comment
возможный дубликат replace() и replaceAll() в Java   -  person user2864740    schedule 13.12.2013
comment
Если вы еще не рассмотрели это, если ввод каким-либо образом поступил от пользователя, вы также можете сначала заменить любые обратные косые черты двойными обратными косыми чертами. Например, если пользователь вводит "You are 'awesome'\'amazing'", вы в настоящее время получите "You are \'awesome\'\\'amazing\'". Это оставляет третью кавычку без экранирования, потому что введенная пользователем обратная косая черта экранирует сгенерированный после нее обратный слэк!   -  person tobii    schedule 21.12.2013


Ответы (6)


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

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

вывод:

You\'ll be totally awesome, I\'m really terrible
person Sage    schedule 12.12.2013
comment
Matcher.quoteReplacement(\\') можно использовать для заключения строки замены в кавычки. - person isnot2bad; 13.12.2013
comment
@ isnot2bad Я действительно думаю, что использование Matcher.quoteReplacement почти само по себе заслуживает ответа. (Это quoteReplacement, а не quoteRegex по причине.) - person user2864740; 13.12.2013
comment
@ user2864740, не могли бы вы немного уточнить. Я объяснил это с точки зрения последовательности символов функции замены, так как в этом случае нам не понадобятся четыре обратных слэша, а только два, как ответил Nambari. - person Sage; 13.12.2013
comment
Моя жалоба связана с .. из-за неправильного регулярного выражения .. . Это строка замены, а не регулярное выражение. - person user2864740; 13.12.2013
comment
@ user2864740, да, но я имел в виду, что для замены этим регулярным выражением replaceAll нам нужно будет повторно экранировать его - person Sage; 13.12.2013
comment
Регулярное выражение обозначается строковым литералом "'". Метод не является регулярным выражением, но он использует регулярное выражение. - person user2864740; 13.12.2013
comment
Не могли бы вы сказать мне, что делать, если мне нужно заменить " на \"? - person Girdhari Agrawal; 11.08.2016
comment
это не работает, пожалуйста, предложите другой метод - person Dinesh Pathak DK; 23.10.2018

Используйте заменить()

 s = s.replace("'", "\\'"); 

выход:

Ты будешь совершенно потрясающим, я действительно ужасен

person kosa    schedule 12.12.2013
comment
@BoristheSpider: replaceall() отличается от replace(). Я не думаю, что OP нужно регулярное выражение здесь. - person kosa; 13.12.2013
comment
это не работает, пожалуйста, предложите какой-нибудь другой метод - person Dinesh Pathak DK; 23.10.2018

Давайте ознакомимся с String#repalceAll(регулярное выражение строки, замена строки)

Вы увидите, что:

Вызов этого метода формы str.replaceAll(regex, repl) дает точно такой же результат, как и выражение

Pattern.compile(regex).matcher(str).replaceAll(repl)

Итак, давайте взглянем на Matcher.html#replaceAll(java.lang.String) документация

Обратите внимание, что обратная косая черта (\) и знаки доллара ($) в замещающей строке могут привести к тому, что результаты будут другими, чем если бы она рассматривалась как буквальная заменяющая строка. Знаки доллара могут рассматриваться как ссылки на захваченные подпоследовательности, как описано выше, а обратная косая черта используется для экранирования буквенных символов в строке замены.

Вы можете видеть, что в replacement у нас есть специальный символ $, который можно использовать как ссылку на захваченную группу, например

System.out.println("aHellob,aWorldb".replaceAll("a(\\w+?)b", "$1"));
// result Hello,World

Но иногда мы не хотим, чтобы $ был таким особенным, потому что мы хотим использовать его как простой символ доллара, поэтому нам нужен способ избежать его.
А вот и \, поскольку он используется для экранирования метасимволов в регулярных выражениях. , строки и, возможно, в других местах, это хорошее соглашение, чтобы использовать его здесь, чтобы экранировать $.

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

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


Поэтому постарайтесь

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

Или даже лучше

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

s = s.replace("'", "\\'");
person Pshemo    schedule 13.12.2013

Здесь не говорится, как «исправить» проблему — это уже было сделано в других ответах; он существует, чтобы извлекать детали и соответствующие ссылки на документацию.


При использовании String.replaceAll или любой из применимых заменителей Matcher, обратите внимание на строку замены и на то, как она обрабатывается:

Обратите внимание, что обратная косая черта (\) и знаки доллара ($) в замещающей строке могут привести к тому, что результаты будут отличаться от тех, которые были обработаны как буквальная заменяющая строка. Знаки доллара могут рассматриваться как ссылки на захваченные подпоследовательности, как описано выше, а обратная косая черта используется для экранирования буквенных символов в строке замены.

Как указано в комментарии isnot2bad, Matcher.quoteReplacement может пригодиться здесь:

Возвращает буквальную замену String для указанной строки. .. Полученная строка будет соответствовать последовательности символов в s, рассматриваемой как литеральная последовательность. Косая черта (\) и знак доллара ($) не будут иметь особого значения.

person user2864740    schedule 13.12.2013

Вы также можете попробовать использовать что-то вроде StringEscapeUtils, чтобы сделать вашу жизнь еще проще: http://commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/apache/commons/lang/StringEscapeUtils.html

s = StringEscapeUtils.escapeJava(s);
person LeoPleurodon    schedule 12.12.2013

Вы можете использовать библиотеку Apache commons-text (вместо commons-lang):

Пример кода:

org.apache.commons.text.StringEscapeUtils.escapeJava(escapedString);

Зависимость:

compile 'org.apache.commons:commons-text:1.8'

OR

<dependency>
   <groupId>org.apache.commons</groupId>
   <artifactId>commons-text</artifactId>
   <version>1.8</version>
</dependency>
person Bogdan Kobylynskyi    schedule 08.04.2020