使用Java/Groovy替换字符串中的反斜杠

6
尝试使用Groovy脚本进行简单的字符串替换,但无法成功。尝试了各种方法,包括以不同方式转义字符串,但仍无法解决问题。
String file ="C:\\Test\\Test1\\Test2\\Test3\\"
String afile = file.toString() println
"original string: " + afile
afile.replace("\\\\", "/")
afile.replaceAll("\\\\", "/") println
"replaced string: " + afile

这段代码的结果是:
original string: C:\Test\Test1\Test2\Test3\
replaced string: C:\Test\Test1\Test2\Test3\

----------------------------

受Sorrow启发,答案如下:

答案如下,受Sorrow的启示:

  // first, replace backslashes
  String afile = file.toString().replaceAll("\\\\", "/")
  // then, convert backslash to forward slash
  String fixed = afile.replaceAll("//", "/")  

2
你的答案部分对我来说没有任何意义:首先,assert file.class == file.toString().class,所以 toString() 是多余的。然后,您正确地将所有单个反斜杠实例替换为正斜杠,以便 assert afile == 'C:/Test/Test1/Test2/Test3/' 但是,然后您尝试替换所有连续两个正斜杠的实例(在字符串中不存在,请参见前面的 assert)为单个正斜杠?这个问题的简单答案是:String result = file.replaceAll('\\\\', '/'),不需要更多。 - Stefan van den Akker
7个回答

11

replace 方法返回一个不同的字符串。在 Java 中,String 不能被修改,所以您需要将替换的结果赋值给某个变量,然后打印出来。

String other = afile.replaceAll("\\\\", "/")
println "replaced string: " + other

编辑:如Neftas在评论中指出的,\是正则表达式中的特殊字符,因此必须要进行两次转义。


你的建议让我意识到了我的错误。但是,我需要做的与你的答案不同。首先,使用你的方法,我必须在第二个replaceAll调用中将双反斜杠替换为正斜杠。信不信由你,我无法同时完成这两个任务。你上面的答案中的代码并没有起作用。 - djangofan
1
这个答案是不正确的。String.replaceAll 的第一个参数应该是一个正则表达式模式,正如其他人所指出的那样,由于 \ 既是字符串和正则表达式的转义字符,你实际上需要输入 \\ 才能让正则表达式引擎得到一个字面上的 \。如果你按照现在的代码运行它,你会得到一个 java.util.regex.PatternSyntaxException 异常。 - Stefan van den Akker
1
@Neftas更新了答案;感谢您指出(我可能应该在粘贴代码之前测试它,或者至少在原始答案中提到我没有尝试过它-好吧,这是一个教训)。 - Miki

10
在Groovy中,甚至无法编写\\ - 它是“不支持的转义序列”。因此,我在这里看到的所有答案都是不正确的。
如果你想表示一个反斜杠,你应该写\\\\。所以,将反斜杠改为正斜杠的代码如下:
scriptPath = scriptPath.replaceAll("\\\\", "/")

如果你想替换成对的反斜杠,那么你需要付出双倍的努力:

scriptPath = scriptPath.replaceAll("\\\\\\\\", "/")

刚刚我有意启动了Gradle/Groovy脚本,这些代码行已经成功使用了一次 - 只是为了确保。

更有趣的是,在StackOverflow上展示这些必要的八个反斜杠“\\\\\\\\”在普通文本中,我必须使用十六个!抱歉,我不会向你展示这十六个,因为我需要32个!而且这永远不会结束......


2
如果你正在处理路径,最好使用java.io.File对象。它会自动将给定的路径转换为正确的操作系统相关路径。例如,在Windows上:
String path = "C:\\Test\\Test1\\Test2\\Test3\\";

// Prints C:\Test\Test1\Test2\Test3
System.out.println(new File(path).getAbsolutePath());

path = "/Test/Test1/Test2/Test3/";

// Prints C:\Test\Test1\Test2\Test3
System.out.println(new File(path).getAbsolutePath());

2

1) afile.replace(...)不会修改你调用它的字符串,它只返回一个新的字符串。

2) 从Java的角度来看,输入的字符串(String file ="C:\\Test\\Test1\\Test2\Test3\\";)只包含单个反斜杠。第一个反斜杠是转义字符,然后第二个反斜杠告诉它你实际上想要一个反斜杠。

因此:

afile.replace("\\\\", "/");
afile.replaceAll("\\\\", "/");

应该是...

afile = afile.replace("\\", "/");
afile = afile.replaceAll("\\", "/");

3
这不是真的 - replaceAll(与replace相比)需要一个正则表达式模式,并且 \ 既是Java字符串文字的转义字符,也是正则表达式的转义字符,这意味着 "\\" 是匹配单个反斜杠的模式。 - Michael Schmeißer

1
在Groovy中,您也可以使用正则表达式,如下所示:

afile = afile.replaceAll(/(\\)/, "/")
println("replaced string: "+ afile)

请注意(正如Sorrow所说),replaceAll返回结果,不会修改字符串。因此,在打印之前,您需要将其分配给一个变量。

0

字符串对象是不可变的,所以如果您调用修改字符串对象的方法,它将始终返回一个新的字符串对象(已修改)。因此,您需要将replaceAll()方法返回的结果存储到一个字符串对象中。


0

此处所发现,最佳选择可能是使用 static Matcher 方法:

Matcher.quoteReplacement( ... )

根据我的实验,这会将单个反斜杠加倍。尽管方法名称...以及略微神秘的Javadoc:“反斜杠('\')和美元符号('$')将不会被赋予任何特殊含义”


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接