Почему я получаю исключение StringIndexOutOfBoundsException при попытке заменить `\\` на `\`? - PullRequest
12 голосов
/ 26 июня 2009

Я должен заменить \\ на \ в 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 опубликовал нужный мне код, но я не знаю, почему он его удалил. В любом случае вот оно.

В базе данных ошибок Java уже зарегистрирована ошибка . (Спасибо за эту ссылку, асаламон.)

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

Удивительно, но и поиск и замена строки одинаковы :), но все равно он делает то, что мне нужно.

Ответы [ 9 ]

17 голосов
/ 26 июня 2009

Используйте 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());

, который будет делать правильные вещи автоматически.

8 голосов
/ 26 июня 2009

Ну, я пытался

    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 слешей)
то же самое для замены ...

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

Для регулярного выражения, если вы хотите изменить \ на \\, вы должны сделать это:

if (str.indexOf('\\') > -1)
    str = str.replaceAll("\\\\", "\\\\\\\\");
str = "\"" + str + "\"";

Где \\\\ означает \, а \\\\\\\\ означает \\.

1 голос
/ 19 декабря 2011

Лучший способ это:

str.replace(**'**\\**'**, **'**/**'**); //with char method not String
1 голос
/ 20 августа 2010

Попробуйте это

cadena.replaceAll("\\\\","\\\\\\\\")
1 голос
/ 26 июня 2009

File.seperator уже экранирован, как и любой строковый объект, поэтому вы экранируете их дважды.

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

0 голосов
/ 10 февраля 2010
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);
0 голосов
/ 26 июня 2009

Я считаю, что вам нужно сделать:

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)

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

0 голосов
/ 26 июня 2009

Я подозреваю, что проблема в том, что replaceAll() использует регулярные выражения, а обратная косая черта является escape-символом как в регулярных выражениях, так и в Java - может потребоваться удвоение количества обратных косых черт.

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

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