【问题标题】:How to replace one or more \ in string with just \?如何用 \ 替换字符串中的一个或多个 \?
【发布时间】:2014-07-15 04:43:54
【问题描述】:

考虑字符串,

this\is\\a\new\\string

输出应该是:

this\is\a\new\string

所以基本上一个或多个\ 字符应该只替换为一个\。 我尝试了以下方法:

str = str.replace("[\\]+","\")

但这没有用。我在[\\]+ 中使用两个\ 的原因是因为内部\ 存储为\\。我知道这可能是一个基本的正则表达式问题,但我可以替换一个或多个普通字母,但不能替换 \ 字符。非常感谢任何帮助。

【问题讨论】:

    标签: java regex string replace replaceall


    【解决方案1】:

    str.replace("[\\]+", "\")问题很少,

    • replace 不使用正则表达式(replaceAll 使用)所以"[\\]" 将代表[\] 文字,而不是\\\(取决于你认为它代表什么)
    • 即使它确实接受正则表达式 "[\\]" 也不是正确的正则表达式,因为 \\] 会转义 ] 所以你最终会得到未封闭的字符类 [..
    • 它不会编译(你的替换字符串没有关闭)

    它不会编译,因为\ 是转义序列\X 的开始,其中X 必须是其中一个

    • 从 String 特殊字符更改为简单文字,例如在您的情况下,\" 将转义 " 为文字(例如,您可以打印它)而不是字符串的开始/结束,
    • 从普通字符更改为特殊字符,例如行分隔符\n\r 或制表符\t

    现在我们知道\ 是特殊的,用于转义其他字符。那么你认为我们需要做什么才能让\ 代表文字(当我们想要打印\ 时)。如果您猜想它需要用另一个 \ 转义,那么您是对的。要创建 \ 字面量,我们需要将其写入 String 为 "\\"

    既然您知道如何创建包含 \ 文字(转义的 \)的字符串,您就可以开始考虑如何创建替换。

    代表一个或多个\的正则表达式看起来像

    \\+

    但这是它的原生形式,我们需要使用 String 来创建它。我在这里使用了\\,因为在正则表达式中\ 也是特殊字符(例如\d 代表digits,而不是\ 文字后跟d)所以它也需要转义首先表示 \ 文字。就像在 String 中一样,我们可以用另一个 \ 转义它。

    所以表示这个正则表达式的字符串需要写成

    "\\\\+"(我们转义了两次\,一次在正则表达式\\+,一次在字符串中)

    您可以将它用作replaceAll 的第一个参数(因为前面提到的replace 不接受正则表达式)。

    现在您将面临的最后一个问题是replaceAll 方法的第二个参数。如果你写

    replaceAll("\\\\+", "\\")

    它会找到匹配的正则表达式,你会看到异常

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

    这是因为在replacement 部分(replaceAll 方法中的第二个参数)我们还可以使用特殊公式$x,它表示来自索引为x 的组的当前匹配。因此,为了能够将$ 转义为文字,我们需要一些转义机制,这里再次使用\ 来达到此目的。 所以\ 也是我们方法的替换部分
    所以再次创建\ 文字,我们需要用另一个\ 对其进行转义,表示表达式\\ 的字符串文字是"\\\\"

    但是让我们回到之前的异常:消息“要转义的字符丢失”指的是\X 公式的X 部分(X 是我们想要转义的字符)。问题是您之前的替换 "\\" 仅代表 \ 部分,因此此方法期望 $ 创建 \$\\ 创建 \ 文字。所以有效的替换是"\\$"\\\\"


    要使事情正常工作,您需要将替换方法编写为

    str = str.replaceAll("\\\\+", "\\\\")
    

    【讨论】:

    • 现在解释得很好!!我不知道的一件事是:replace 不需要正则表达式,而且 IllegalArgumentException 非常有用!我有时会忘记这一点!非常感谢!
    • 我可以推荐Matcher.quoteReplacement() 来转义替换字符串。喜欢str = str.replaceAll("\\\\+", Matcher.quoteReplacement("\\"))
    • @MichaF。是的,如果我们想避免手动转义,或者由于在运行时动态提供替换(例如从控制台或文件)而无法做到这一点,这可能会很有用。
    【解决方案2】:

    你可以使用:

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

    请记住,String#replace 不使用正则表达式。

    【讨论】:

    • 这很奇怪!我不知道 String#replace 不接受正则表达式!我使用了 Pattern,Matcher,它现在可以工作了!谢谢。`Matcher m = Pattern.compile("[\\\]+").matcher(str);if(m.find())path=m.replaceAll("\\\\");}'
    • 这不适用于以下输入:String s = "this\\is\\\\a\\new\\\\\\string";,或连续有两个以上反斜杠的任何内容。
    【解决方案3】:

    试试这个

    str = str.replaceAll("\\\\+", "\\\\");
    

    【讨论】:

      【解决方案4】:

      在编写正则表达式时,通常需要双转义反斜杠。所以你会这样做:

      str = str.replaceAll("\\\\+", "\\\\");
      

      【讨论】:

      • replace 不会将第一个参数视为正则表达式。您可能想要replaceAll,但在这种情况下,您还需要在第二个参数中转义两次\\
      • @Pshemo 我在您发表评论之前将replace 更正为replaceAll,但实际上您对替换字符串是正确的。现已修复。
      【解决方案5】:

      我会在这里使用Matcher.quoteReplacement()String.replaceAll()

      像这样:

      String s;
      [...]
      s = s.replaceAll("\\\\+", Matcher.quoteReplacement("\\"));
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-01-16
        • 2021-11-25
        • 1970-01-01
        • 2016-12-03
        • 2010-10-23
        • 1970-01-01
        相关资源
        最近更新 更多