【问题标题】:Java: Replace all ' in a string with \'Java:用\'替换字符串中的所有'
【发布时间】:2013-12-31 14:35:23
【问题描述】:

我需要转义字符串中的所有引号('),所以它变成\'

我尝试过使用 replaceAll,但它什么也没做。由于某种原因,我无法让正则表达式工作。

我正在尝试

String s = "You'll be totally awesome, I'm really terrible";
String shouldBecome = "You\'ll be totally awesome, I\'m really terrible";
s = s.replaceAll("'","\\'"); // Doesn't do anything
s = s.replaceAll("\'","\\'"); // Doesn't do anything
s = s.replaceAll("\\'","\\'"); // Doesn't do anything

我真的被困在这里,希望有人可以在这里帮助我。

谢谢,

伊万

【问题讨论】:

  • 如果您还没有考虑过这一点,如果输入来自用户,您可能还想先用双反斜杠替换任何反斜杠。就像如果用户输入"You are 'awesome'\'amazing'",那么您当前会得到"You are \'awesome\'\\'amazing\'"。这使得第三个引号没有转义,因为用户输入的反斜杠正在转义它之后生成的反斜杠!

标签: java regex string replaceall


【解决方案1】:

你必须首先转义反斜杠,因为它是一个文字(产生\\),然后因为正则表达式再次转义它(产生\\\\)。所以,试试:

 s.replaceAll("'", "\\\\'");

输出:

You\'ll be totally awesome, I\'m really terrible

【讨论】:

  • Matcher.quoteReplacement("\\'") 可用于引用替换字符串。
  • @isnot2bad 我真的认为Matcher.quoteReplacement 的使用本身几乎值得回答。 (这是quoteReplacement,而不是quoteRegex。)
  • @user2864740,请您详细说明一下。我已经根据替换函数字符序列进行了解释,因为在这种情况下,我们不需要四个反斜杠,而Nambari 只需要两个反斜杠。
  • 我的抱怨是“..因为正则表达式..”,这是错误的。它是replacement string,而不是正则表达式。
  • @user2864740,是的,但我的意思是要替换为 replaceAll 的正则表达式,我们需要重新转义它
【解决方案2】:

使用replace()

 s = s.replace("'", "\\'"); 

输出:

你会非常棒,我真的很糟糕

【讨论】:

  • @BoristheSpider:replaceall() 与 replace() 不同。我认为 OP 在这里不需要正则表达式。
  • 这行不通,请提出其他方法
【解决方案3】:

您也可以尝试使用类似 StringEscapeUtils 的工具来让您的生活更轻松:http://commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/apache/commons/lang/StringEscapeUtils.html

s = StringEscapeUtils.escapeJava(s);

【讨论】:

    【解决方案4】:

    这并没有说明如何“解决”问题 - 这已经在其他答案中完成了;它的存在是为了列出详细信息和适用的文档参考。


    使用String.replaceAll 或任何适用的匹配器替换器时,请注意替换字符串及其处理方式:

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

    正如 isnot2bad 在评论中指出的那样,Matcher.quoteReplacement 在这里可能有用:

    返回指定字符串的文字替换字符串。 .. 生成的 String 将匹配 s 中的字符序列,将其视为文字序列。斜杠 (\) 和美元符号 ($) 将没有特殊含义。

    【讨论】:

      【解决方案5】:

      让我们来看看String#repalceAll(String regex, String replacement)

      你会看到:

      调用这种形式为 str.replaceAll(regex, repl) 的方法会产生与表达式完全相同的结果

      Pattern.compile(regex).matcher(str).replaceAll(repl)

      让我们看看Matcher.html#replaceAll(java.lang.String) 文档

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

      您可以看到在replacement 中我们有特殊字符$ 可以用作捕获组的引用,例如

      System.out.println("aHellob,aWorldb".replaceAll("a(\\w+?)b", "$1"));
      // result Hello,World
      

      但有时我们不希望$ 如此特别,因为我们想将它用作简单的美元字符,所以我们需要一种方法来转义它。
      \ 出现了,因为它用于转义正则表达式、字符串和可能在其他地方的元字符,所以在这里使用它来转义 $ 是一个很好的约定。

      所以现在\ 也是替换部分的元字符,所以如果你想简单地替换\ 文字,你需要以某种方式对其进行转义。你猜怎么着?您以与在正则表达式或字符串中转义它相同的方式转义它。你只需要在你逃跑之前再放一个\

      所以如果你想在替换部分创建\,你需要在它之前添加另一个\。但请记住,要在 String 中写 \ 文字,您需要将其写为 "\\",因此要创建两个 \\ 替换您需要将其写为 "\\\\"


      那就试试吧

      s = s.replaceAll("'", "\\\\'");
      

      甚至更好

      要减少替换部分(以及正则表达式部分 - 前面忘了提到)中的显式转义,只需使用 replace 而不是 replaceAll 为我们添加正则表达式转义

      s = s.replace("'", "\\'");
      

      【讨论】:

        【解决方案6】:

        您可以使用 apache 的 commons-text 库(而不是 commons-lang):

        示例代码:

        org.apache.commons.text.StringEscapeUtils.escapeJava(escapedString);
        

        依赖:

        compile 'org.apache.commons:commons-text:1.8'
        
        OR
        
        <dependency>
           <groupId>org.apache.commons</groupId>
           <artifactId>commons-text</artifactId>
           <version>1.8</version>
        </dependency>
        

        【讨论】:

          猜你喜欢
          • 2012-09-05
          • 2011-11-11
          • 2013-01-04
          • 1970-01-01
          • 2013-11-05
          • 2015-05-01
          • 1970-01-01
          • 2011-06-09
          相关资源
          最近更新 更多