1

以下代码用完全限定类名(可以是任何字符串)中的反斜杠替换所有点。

String str=Test.class.getName().replaceAll("\\.", "\\\\") + ".class";
System.out.println(str);

替换字符串需要四个反斜杠。


假设替换字符串是文件路径中的分隔符,我想使用java.io.File.separator.

String separator=File.separator+File.separator
String str=Test.class.getName().replaceAll("\\.", separator) + ".class "
System.out.println(str);

在这种情况下,它只使用两个反斜杠。为什么不像前一种情况那样需要四个反斜杠?

4

5 回答 5

5

Java 字符串由字符组成。为了允许 Java 程序员将字符串作为“常量”和 Java 代码的一部分输入,该语言允许您将它们输入为用“””引号括起来的字符.....

 String str = "this is a string";

有些字符很难输入到程序中,例如换行符或制表符。Java 引入了一种转义机制,允许程序员将这些字符输入到字符串中。转义机制是“\”反斜杠。

 String str = "this contains a tab\t and newline\n";

问题是现在没有简单的方法来输入反斜杠,所以输入反斜杠必须自己转义:

 String str = "this contains a backslash \\"

下一个问题是正则表达式是复杂的东西,它们还使用反斜杠\作为转义字符。

Now in, for example, perl, the regular expression \. would match the exact character '.' because in regular expressions the '.' is special, and needs to be escaped with a '\'. To capture that sequence \. in a Java program (as a string constant in the program) we will need to escape the '\' as \\ and our Java equivalent regular expression is \\.. Now, in perl, again, the regular expression to match the actual backslash character is \\. Similarly, we need to escape both of these in Java in the actual code, and it is \\\\.

所以,这里的意义在于windows中的文件分隔符是反斜杠\。此单个字符存储在字段 File.separator 中。如果我们想从 Java 程序中输入相同的字符,我们必须将其转义为\\,但是 '\' 已经存储在该字段中,因此我们不需要为 Java 程序重新转义它,但是我们确实需要为正则表达式转义它....

对于正则表达式,有两种方法可以对其进行转义。您可以选择在它之前添加一个反斜杠:

"\\" + File.separator 

但这是一种不好的方法,因为它在 Unix 上不起作用(分隔符不需要转义。更糟糕的是做你所做的,即加倍文件分隔符:

File.separator+File.separator

The right way to do it is to correctly escape the replacement side of the regular expression with Matcher.quoteReplacement(...)

System.out.println(Test.class.getName().replaceAll("\\.",
      Matcher.quoteReplacement(File.separator)) + ".class ")
于 2013-11-02T19:22:52.697 回答
3

四个反斜杠用于对方法使用的两个反斜杠进行编码。"\\\\"被解释为:

"\\" (an escaped backslash)
"\\" (another escaped backslash)

第一个和第三个反斜杠用于转义字符串中的第二个和第四个反斜杠。如果反斜杠存储在诸如 之类的变量中File.separator,则它们不是必需的。

要获得更清晰的答案,请尝试以下代码:

System.out.println("\\\\");

它打印\\

于 2013-11-02T19:03:49.927 回答
2

因为File.separator

public static final String separator = "" + separatorChar;
public static final char separatorChar = fs.getSeparator(); //gotten from system properties

文件分离separatorChar的特定系统在哪里。char在这种情况下,您无需逃避任何事情。

为什么不像前一种情况那样需要四个反斜杠?

转义用于String文字。

什么fs.getSeparator()是(简单来说)

System.getProperty("file.separator");

在 Windows 上返回String \. getSeperator()然后获取该charAt(0)字符串的 char '\'。与inString连接时会转换为 a""

public static final String separator = "" + separatorChar;

这是在运行时完成的,因此不会评估为String文字,因此不需要转义。

于 2013-11-02T19:04:17.483 回答
1

您应该使用replace()它接收纯文本,而replaceAll()采用正则表达式:

.replace(".", "\\");

关于文件分隔符,您可以使用它,/因为它可以在 Java 中的所有操作系统上运行。

于 2013-11-02T19:02:28.833 回答
1

From the javadoc for Matcher.#appendReplacement

Note that backslashes (\) and dollar signs ($) in the replacement string may cause the results to be different than if it were being treated as a literal replacement string. Dollar signs may be treated as references to captured subsequences as described above, and backslashes are used to escape literal characters in the replacement string.

You need to quote the backslash in replacement, hence the four backslashes.

You could use Pattern#quote to make your method portable.

As pointed by @rolfl you have to use Matcher#quoteReplacement to quote the replacement string.

System.out.println(Test.class.getName().replaceAll("\\.",
    Matcher.quoteReplacement(File.separator)) + ".class ");
于 2013-11-02T19:29:53.893 回答