【问题标题】:Replacing double backslashes with single backslash用单反斜杠替换双反斜杠
【发布时间】:2012-06-16 06:08:18
【问题描述】:

我有一个字符串“\\u003c”,它属于 UTF-8 字符集。由于存在双反斜杠,我无法将其解码为 un​​icode。我如何从“\\u003c”中得到“\\u003c”?我正在使用 java。

我试过了,

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

但无法实现我想要的。

这是我的代码,

String myString = FileUtils.readFileToString(file);
String a = myString.replace("\\\\", "\\");
byte[] utf8 = a.getBytes();

// Convert from UTF-8 to Unicode
a = new String(utf8, "UTF-8");
System.out.println("Converted string is:"+a);

文件的内容是

\u003c

【问题讨论】:

  • 你能贴出你用来解码字符串的代码吗?

标签: java string character-encoding replace backslash


【解决方案1】:

你可以使用String#replaceAll:

String str = "\\\\u003c";
str= str.replaceAll("\\\\\\\\", "\\\\");
System.out.println(str);

看起来很奇怪,因为第一个参数是一个定义正则表达式的字符串,而\ 在字符串字面量中都是一个特殊字符。要在我们的搜索字符串中实际放置一个\,我们需要在文字中转义它(\\)。但要真正将\ 放入正则表达式,我们必须在正则表达式级别以及对其进行转义。所以要从字面上得到\\,我们需要在字符串文字中写\\\\;为了得到两个文字\\到正则表达式引擎,我们也需要转义它们,所以我们最终得到\\\\\\\\。那就是:

字符串文字字符串含义到正则表达式 ------------------------------------------------------ −−−−−−−−−−−−−−−− \ 转义下一个字符 取决于下一个字符 \\ \ 转义下一个字符 \\\\ \\ 字面量 \ \\\\\\\\ \\\\ 字面意思 \\

在替换参数中,即使它不是正则表达式,它仍然会特别对待\$——因此我们也必须在替换中对它们进行转义。因此,要在替换中获得一个反斜杠,我们需要在该字符串文字中添加四个。

【讨论】:

  • 该线程中唯一简短且正确的答案 :) 是的,第一个和第二个参数都必须将 \ 翻两番,因为实际上两个字符串都是特殊的正则表达式字符串,而不是常规字符串。
  • @jakub.g:您应该发布replace 答案。正如您在我现在已删除的答案中所说,如果您的目标是用 \ 替换 \\replaceAll 就是错误的工具。
  • @T.J.Crowder 我花了一段时间,但我终于发布了replace 答案!
  • 这是我没有真正写过的最佳答案!归功于@T.J.Crowder!
  • @mtyson - 稍微充实了一点。 ;-) 当 SO 的协作方面起作用时,我喜欢它。
【解决方案2】:

不确定您是否仍在寻找问题的解决方案(因为您有一个已接受的答案),但我仍会将我的答案添加为所述问题的可能解决方案:

String str = "\\u003c";
Matcher m = Pattern.compile("(?i)\\\\u([\\da-f]{4})").matcher(str);
if (m.find()) {
    String a = String.valueOf((char) Integer.parseInt(m.group(1), 16));
    System.out.printf("Unicode String is: [%s]%n", a);
}

输出:

Unicode String is: [<]

Here is online demo of the above code

【讨论】:

  • 神奇地将“\\”替换为“\”。谢谢
  • 问题仍然存在:为什么首先在字符串中存在双反斜杠?
  • @EJP 你好。我确信 myString 中有 bouble 反斜杠。当我在源代码中将“\u003c”分配给 myString 并在将其打印到控制台后不久,它会给出“
【解决方案3】:

关于“用单反斜杠替换双反斜杠”或更一般地,“将包含\的简单字符串替换为包含\的不同简单字符串”的问题(这不完全是OP问题,但它的一部分):

这个帖子中的大多数答案都提到了replaceAll,这是一个错误的工具。更简单的工具是replace,但令人困惑的是,OP 声明replace("\\\\", "\\") 对他不起作用,这可能就是为什么所有答案都集中在replaceAll 上。

对于有 JavaScript 背景的人的重要提示请注意,Java 中的 replace(CharSequence, CharSequence) 确实替换了所有出现的子字符串 - 与 JavaScript 不同,它只替换第一个!

用指定的文字替换序列替换此字符串中与文字目标序列匹配的每个子字符串。

另一方面,replaceAll(String regex, String replacement) -- 更多文档 also here -- 将这两个参数视为比常规字符串更多:

请注意,替换字符串中的反斜杠 () 和美元符号 ($) 可能会导致结果与将其视为文字替换字符串时的结果不同。

(这是因为\$ 可以用作对捕获的正则表达式组的反向引用,因此如果要按字面意思使用它们,则需要转义它们。

换句话说,replacereplaceAll 的第一个和第二个参数的行为不同。对于replace,您需要将两个参数中的\ 加倍(字符串文字中反斜杠的标准转义),而在replaceAll 中,您需要将其加倍! (标准字符串转义 + 函数特定转义)

总结一下,对于简单的替换,应该坚持replace("\\\\", "\\")(只需要转义一个,不需要转义两个)。

https://ideone.com/ANeMpw

System.out.println("a\\\\b\\\\c");                                 // "a\\b\\c"
System.out.println("a\\\\b\\\\c".replaceAll("\\\\\\\\", "\\\\"));  // "a\b\c"
//System.out.println("a\\\\b\\\\c".replaceAll("\\\\\\\\", "\\"));  // runtime error
System.out.println("a\\\\b\\\\c".replace("\\\\", "\\"));           // "a\b\c"

https://www.ideone.com/Fj4RCO

String str = "\\\\u003c";
System.out.println(str);                                // "\\u003c"
System.out.println(str.replaceAll("\\\\\\\\", "\\\\")); // "\u003c"
System.out.println(str.replace("\\\\", "\\"));          // "\u003c"

【讨论】:

    【解决方案4】:

    另一种选择,捕获两个斜线之一并将两个斜线替换为捕获的组:

    public static void main(String args[])
    {
        String str = "C:\\\\";
        str= str.replaceAll("(\\\\)\\\\", "$1");
    
        System.out.println(str);
    } 
    

    【讨论】:

      【解决方案5】:

      尝试使用,

      myString.replaceAll("[\\\\]{2}", "\\\\");

      【讨论】:

        【解决方案6】:

        这是为了将双反斜杠替换为单反斜杠

        public static void main(String args[])
        {
              String str = "\\u003c";
              str= str.replaceAll("\\\\", "\\\\");
        
              System.out.println(str);
        }
        

        【讨论】:

        • java 7 有什么变化吗?此代码不再有效。 Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 1
        【解决方案7】:

        "\\u003c" 根本不“属于 UTF-8 字符集”。它是 五个 UTF-8 字符:'\'、'0'、'0'、'3' 和 'c'。这里真正的问题是为什么那里有双反斜杠?或者,他们真的在那里吗?您的问题可能完全不同吗?如果字符串"\\u003c" 在您的源代码中,则在运行时根本没有双反斜杠,无论您的问题是什么,它都与存在双反斜杠的解码无关。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2013-06-24
          • 1970-01-01
          • 1970-01-01
          • 2013-04-15
          • 1970-01-01
          • 2017-07-25
          • 2011-09-06
          相关资源
          最近更新 更多