我需要澄清“缺少要转义的字符”异常

时间:2018-08-06 08:05:17

标签: java string

我有以下代码:

public class Test {

public static void main(String[] args) {
    String path = "${file.path}/fld/";
    String realValue = "C:\\path\\smtg\\";
    String variable = "${file.path}";
    path = path.replaceAll("\\$\\{" + variable.substring(2, variable.length() - 1) + "\\}", realValue);
    System.out.println(path);
    }
}

这给了我以下异常:

Exception in thread "main" java.lang.IllegalArgumentException: character to be escaped is missing
at java.util.regex.Matcher.appendReplacement(Matcher.java:809)
at java.util.regex.Matcher.replaceAll(Matcher.java:955)
at java.lang.String.replaceAll(String.java:2223)
at testCode.Test.main(Test.java:9)

我已经找到有关此问题的一些问题,但我仍然不明白此错误。有人可以解释我发生了什么吗?

我知道replace可以很好地工作,但是很不幸,我的同事们不想修改此代码。因此,我需要知道提供解决方案的确切问题,因为在其他安装中它可以工作。

4 个答案:

答案 0 :(得分:4)

对于您的特殊情况,您需要执行以下操作:

public static void main(String[] args) {
    String path = "${file.path}/fld/";
    String realValue = "C:\\\\path\\\\smtg\\\\";  //Notice the double slashes here
    String variable = "${file.path}";
    path = path.replaceAll("\\$\\{" + variable.substring(2, variable.length() - 1) + "\\}", realValue);
    System.out.println(path);
}

现在进行解释。当您执行replaceAll时,字符串的第二部分也将由Java解释,并具有特殊字符,例如\$。因此,为了在字符串中添加\,您需要对其进行转义并将其变为\\,如果您想在结果字符串文字中使用它,则需要对它们中的每一个进行转义,使其变为{{1} }

如果您在匹配器中的replaceAll方法上检查java doc: https://docs.oracle.com/javase/7/docs/api/java/util/regex/Matcher.html#replaceAll%28java.lang.String%29

  

请注意,替换中的反斜杠(\)和美元符号($)   字符串可能会导致结果与原来的结果有所不同   视为文字替换字符串。美元符号可能会被处理   作为对如上所述捕获的子序列的引用,以及   反斜杠用于在替换中转义文字字符   字符串。

在您的情况下,一种更简单的解决方案是使用"\\\\"而不是replace,因为您的模式非常简单,并且不需要正则表达式支持,您可以将其与一个完整的字符串匹配” $ {file.path}“

replaceAll

答案 1 :(得分:0)

更改路径String realValue =“ C:// path // smtg //”并尝试

public class Test {

public static void main(String[] args) {
String path = "${file.path}/fld/";
String realValue = "C://path//smtg//";
String variable = "${file.path}";
path = path.replaceAll("\\$\\{" + variable.substring(2, variable.length() - 1) + "\\}", realValue);
System.out.println(path);
}
}

答案 2 :(得分:0)

ReplaceAll将其输入视为正则表达式。正则表达式中有一些有效的转义表达式,例如\w表示单词字符或\s表示空格。如果file.path是包含\的Windows路径,则很可能具有无效的转义序列。无论如何,它都不具有您想要的含义。

起作用的其他情况是它们是否在类似Unix的环境中? (unix,linux,os-x等)(如果可以),因为这些环境使用/作为路径分隔符。

在致电replaceAll之前,您可以尝试

variable = variable.replace("\\", "\\\\"); // to escape any \ in path.

答案 3 :(得分:0)

replaceAll(regexString, replacementString)

规则1:
第一个输入接受一个正则表达式,在您的情况下,可读性较低。

规则2:
第二个输入按原样接受字符串文字替换,但是根据replaceAll文档,替换字符串中的$\字符给出的结果与预期不同,因此这导致{{1 }}。

解决方案摘要:

java.lang.IllegalArgumentException: character to be escaped is missing