Почему я получаю исключение StringIndexOutOfBoundsException, когда пытаюсь заменить `\\` на `\`?
Мне нужно заменить \\
на \
на Java. Код, который я использую,
System.out.println( (MyConstants.LOCATION_PATH + File.separator + myObject.getStLocation() ).replaceAll("\\\\", "\\") );
Но я не знаю, почему он бросает StringIndexOutOfBoundsException
.
В нем говорится String index out of range: 1
В чем может быть причина? Я думаю, это потому, что первый аргумент replaceAll
принимает шаблон. Каким может быть возможное решение?
StackTrace
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 1
at java.lang.String.charAt(String.java:558)
at java.util.regex.Matcher.appendReplacement(Matcher.java:696)
at java.util.regex.Matcher.replaceAll(Matcher.java:806)
at java.lang.String.replaceAll(String.java:2000)
Найден ответ
asalamon74 разместил код, который мне нужен, но я не знаю, почему он его удалил. В любом случае это так.
Существует bug, уже зарегистрированный в базе данных ошибок Java. (Спасибо за эту ссылку, асаламон.)
yourString.replaceAll("\\\\", "\\\\");
Удивительно, что строка поиска и замены одинакова:), но все же она делает то, что мне нужно.
Ответы
Ответ 1
Используйте String.replace
вместо replaceAll
, чтобы избежать использования регулярного выражения:
String original = MyConstants.LOCATION_PATH + File.seperator
+ myObject.getStLocation();
System.out.println(original.replace("\\\\", "\\"));
Лично я бы этого не делал, но я создал MyConstants.LOCATION_PATH_FILE как File
, а затем вы могли бы написать:
File location = new File(MyConstants.LOCATION_PATH_FILE,
myObject.getStLocation());
который будет делать правильную вещь автоматически.
Ответ 2
Ну, я попробовал
String test = "just a \\ test with some \\\\ and others \\\\ or \\ so";
String result = test.replaceAll("\\\\", "\\\\");
System.out.println(test);
System.out.println(result);
System.out.println(test.equals(result));
и получил, как ожидалось
just a \ test with some \\ and others \\ or \ so
just a \ test with some \\ and others \\ or \ so
true
Что вам действительно нужно
string.replaceAll("\\\\\\\\", "\\\\");
чтобы получить
just a \ test with some \\ and others \\ or \ so
just a \ test with some \ and others \ or \ so
false
Вы хотите найти: \\
(2 слэша)
который должен быть экранирован в регулярном выражении: \\\\
(4 слэша)
и сбежал в Java: "\\\\\\\\"
(8 слэшей)
то же самое для замены...
Ответ 3
Для регулярного выражения, если вы хотите изменить \
на \\
, вы должны сделать это:
if (str.indexOf('\\') > -1)
str = str.replaceAll("\\\\", "\\\\\\\\");
str = "\"" + str + "\"";
Где \\\\
означает \
и \\\\\\\\
означает \\
.
Ответ 4
File.seperator уже экранирован, как и любой строковый объект, поэтому вы избегаете их дважды.
Вам нужно только избежать значений, которые вы вводите в виде строкового литерала.
Ответ 5
Попробуйте это
cadena.replaceAll("\\\\","\\\\\\\\")
Ответ 6
Лучший способ:
str.replace(**'**\\**'**, **'**/**'**); //with char method not String
Ответ 7
Я подозреваю, что проблема заключается в том, что replaceAll()
использует регулярные выражения, а обратная косая черта - это escape-символ в регулярных выражениях, а также в Java - может потребоваться удвоить количество обратных косых черт.
В общем, вы всегда должны публиковать полную трассировку стека исключений, гораздо проще диагностировать проблему таким образом.
Ответ 8
Я считаю, что вам нужно сделать следующее:
System.out.println( (MyConstants.LOCATION_PATH + File.separator + myObject.getStLocation() ).replaceAll("\\\\\\\\", "\\\\") );
Регулярное выражение String на самом деле представляет собой четыре обратной косой черты, которая является регулярным выражением, которое соответствует двум обратным слэшам.
Строка замены должна быть четырьмя слэшами в соответствии с документацией Java, начиная с:
http://java.sun.com/javase/6/docs/api/java/util/regex/Matcher.html#replaceAll(java.lang.String)
Обратите внимание, что обратная косая черта() и знаки доллара ($) в заменяющей строке могут привести к тому, что результаты будут отличаться от того, будут ли они рассматриваться как буквальная строка замены. Знаки доллара могут рассматриваться как ссылки на захваченные подпоследовательности, как описано выше, а обратные косые черты используются для исключения буквенных символов в заменяющей строке.
Ответ 9
final StringBuilder result = new StringBuilder();
final StringCharacterIterator iterator = new StringCharacterIterator(str);
char character = iterator.current();
while (character != CharacterIterator.DONE )
{
if (character == '\\\\') {
result.append("\\");
}
else {
result.append(character);
}
character = iterator.next();
}
System.out.print(result);