繁体   English   中英

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

[英]I need a clarification about "character to be escaped is missing" exception

我有以下代码:

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会很好用,但不幸的是我的同事不想修改这段代码。 所以我需要知道确切的问题来提供解决方案,因为在其他安装中它有效。

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

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 解释并具有特殊字符,如\\$ 因此,为了在字符串中添加 \\,您需要将其转义并变为\\\\ ,如果您想在生成的字符串文字中使用它,则需要对每个字符串进行转义,使其变为"\\\\\\\\"

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

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

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

path = path.replace("${file.path}", realValue);
//or even
path = path.replace(variable, realValue);

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

其他有效的事件是在类似 Unix 的环境中吗? (unix、linux、os-x 等)如果是这样的话,它可能会起作用,因为这些环境使用/作为路径分隔符。

在调用replaceAll之前,您可以尝试

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

更改路径 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);
}
}
replaceAll(regexString, replacementString)

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

规则#2:
第二个输入按原样接受用于替换的字符串文字,但根据replaceAll文档,替换字符串中的$\\字符给出的结果与预期不同,因此这导致java.lang.IllegalArgumentException: character to be escaped is missing

解决方案片段:

public class Main {

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM