当我尝试用“\”替换“\”时,为什么会收到 StringIndexOutOfBoundsException?

问题描述 投票:0回答:9

我必须在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("\\\\", "\\\\");

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

java string
9个回答
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());

它将自动做正确的事情。


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 个斜杠)
更换时也一样。

另请参阅

Pattern
的 javadoc,第 反斜杠、转义符和引用部分。


2
投票

对于正则表达式,如果您想将

\
更改为
\\
,您应该这样做:

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

其中

\\\\
表示
\
\\\\\\\\
表示
\\


1
投票

File.seperator 已经像任何字符串对象一样被转义了,所以你要转义它们两次。

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


1
投票

最好的方法是:

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

1
投票

试试这个

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

0
投票

我怀疑问题在于

replaceAll()
使用正则表达式,而反斜杠是正则表达式以及 Java 中的转义字符 - 可能需要将反斜杠的数量加倍。

一般来说,您应该始终发布异常的完整堆栈跟踪,这样诊断问题要容易得多。


0
投票

我相信你需要做的是:

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)

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


-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);
© www.soinside.com 2019 - 2024. All rights reserved.