当我尝试将`\\`替换为`\`时,为什么会出现StringIndexOutOfBoundsException?

时间:2009-06-26 13:23:26

标签: java string

我必须在Java中用\\替换\。我正在使用的代码是

System.out.println( (MyConstants.LOCATION_PATH + File.separator + myObject.getStLocation() ).replaceAll("\\\\", "\\") );

但我不知道为什么会抛出StringIndexOutOfBoundsException

它说String index out of range: 1

可能是什么原因?我想这是因为第一个参数replaceAll接受了一个模式。可能的解决方案是什么?


堆栈跟踪

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的bug数据库中已经提交了bug。 (感谢您的参考,asalamon。)

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

令人惊讶的是,搜索和替换字符串都是相同的:)但它仍然可以满足我的要求。

9 个答案:

答案 0 :(得分:17)

使用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());

会自动做正确的事。

答案 1 :(得分:8)

好吧,我试过了

    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 :(得分:2)

对于正则表达式,如果要将\更改为\\,则应执行以下操作:

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

其中\\\\表示\\\\\\\\\表示\\

答案 3 :(得分:1)

File.separator已经像任何字符串对象一样进行了转义,因此您可以将它们转义两次。

您只需要将您输入的值转义为字符串文字。

答案 4 :(得分:1)

试试这个

cadena.replaceAll("\\\\","\\\\\\\\")

答案 5 :(得分:1)

最好的方法是:

str.replace(**'**\\**'**, **'**/**'**); //with char method not String

答案 6 :(得分:0)

我怀疑问题是replaceAll()使用正则表达式而反斜杠是regexp和Java中的转义字符 - 可能需要加倍反斜杠的数量。

一般情况下,您应该始终发布完整的异常堆栈跟踪,以这种方式诊断问题要容易得多。

答案 7 :(得分:0)

我相信你需要做的是:

System.out.println( (MyConstants.LOCATION_PATH + File.separator + myObject.getStLocation() ).replaceAll("\\\\\\\\", "\\\\") );

正则表达式String实际上是四个反斜杠,这是一个匹配两个反斜杠的正则表达式。

根据Java文档,替换String必须是四个斜杠,来自: http://java.sun.com/javase/6/docs/api/java/util/regex/Matcher.html#replaceAll(java.lang.String)

  

请注意,替换字符串中的反斜杠()和美元符号($)可能会导致结果与将其视为文字替换字符串时的结果不同。如上所述,美元符号可被视为对捕获的子序列的引用,反斜杠用于替换替换字符串中的文字字符。

答案 8 :(得分:-2)

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);