我是否总是需要在不是“文字”的字符串中转义元字符?

似乎在正则表达式处理期间拒绝包含字符{}的字符串。 我可以理解这些是保留字符,我需要逃避它们,所以如果我这样做:

 string.replaceAll("\\" + pattern); 

这是有效的,其中pattern是以{开头的任何字符串。

问题:是否有办法避免已经包含此类元组的字符串出现此类问题,以便自动处理? 在我看来它应该与在字符串文字中添加双引号相比,接受字符串作为已经具有双引号的输入

使用Pattern.quote(String)

 public static String quote(String s) 

返回指定String的文字模式String

此方法生成一个String ,该String可用于创建与字符串s匹配的Pattern ,就好像它是文字模式一样。

输入序列中的元字符或转义序列将没有特殊含义。

参数:
s – 要文字化的字符串
返回:
文字字符串替换
以来:
1.5

您可以使用

 java.util.regex.Pattern.quote(java.lang.String) 

转义正则表达式使用的元字符。

TL; DR

  • 如果你需要正则表达式语法使用replaceAllreplaceFirst
  • 如果您希望将target/replacement对视为文字,请使用replace (它还会替换所有出现的目标)。

大多数人都对在String类中替换方法的不幸命名感到困惑,这些方法是:

  • replaceAll(String, String)
  • replaceFirst(String, String)
  • replace(CharSequence, CharSequence)
  • replace(char, char)

由于replaceAll方法明确声称它替换了所有可能的目标,因此人们认为replace方法并不能保证这种行为,因为它不包含All后缀。
但这种假设是错误的。

这些方法之间的主要区别如下表所示:

 ╔═════════════════════╦═══════════════════════════════════════════════════════════════════╗ ║ ║ replaced targets ║ ║ ╠════════════════════════════════════╦══════════════════════════════╣ ║ ║ ALL found ║ ONLY FIRST found ║ ╠══════╦══════════════╬════════════════════════════════════╬══════════════════════════════╣ ║ ║ supported ║ replaceAll(String, String) ║ replaceFirst(String, String) ║ ║regex ╠══════════════╬════════════════════════════════════╬══════════════════════════════╣ ║syntax║ not ║ replace(CharSequence, CharSequence)║ \/ ║ ║ ║ supported ║ replace(char, char) ║ /\ ║ ╚══════╩══════════════╩════════════════════════════════════╩══════════════════════════════╝ 

现在,如果您不需要使用正则表达式语法使用方法而不期望它,但它将targetreplacement视为文字。

所以代替replaceAll(regex, replacement)

使用replace(literal, replacement)


如您所见,有两个重载的重载版本。 它们都应该适合你,因为它们不支持正则表达式语法。 它们之间的主要区别在于:

  • replace(char target, char replacement)只是创建新的字符串,并用原始字符串中的字符或您决定替换的字符(取决于它是否等于目标字符)填充它

  • replace(CharSequence target, CharSequence replacement)本质上等同于replaceAll(Pattern.quote(target), Matcher.quoteReplacement(replacement.toString()) ,这意味着它与replaceAll相同但是(这意味着它在内部使用正则表达式引擎)但它会逃避target使用的正则表达式元字符并自动replacement

您不需要任何额外的代码,只需要\Q\E构造,如Java的Pattern类中所述 。

例如,在以下代码中:

 String foobar = "crazyPassword=f()ob@r{}+"; Pattern regex = Pattern.compile("\\Q" + foobar "\\E"); 

模式将编译,foobar的特殊字符不会被解释为正则表达式字符。 在这里看演示。

它唯一不匹配的是输入包含文字\E 如果你也需要解决这个问题,请在评论中告诉我,我会编辑添加。