如何在Java中为正则expression式转义文本

Java是否有一种内置的方式来转义任意文本,以便它可以包含在正则expression式中? 例如,如果我的用户input“$ 5”,我希望在input结束后确切地匹配而不是“5”。

从Java 1.5开始,是的 :

Pattern.quote("$5"); 

在我看到下面的例子之前, Pattern.quoteMatcher.quoteReplacement之间的Matcher.quoteReplacement并不清楚

 s.replaceFirst(Pattern.quote("text to replace"), Matcher.quoteReplacement("replacement text")); 

回应可能已经太晚了,但是您也可以使用Pattern.LITERAL ,它可以在格式化时忽略所有特殊字符:

 Pattern.compile(textToFormat, Pattern.LITERAL); 

我想你以后是\Q$5\E 另请参阅Java5中引入的Pattern.quote(s)

有关详细信息,请参阅模式 javadoc。

首先,如果

  • 你使用replaceAll()
  • 你不使用Matcher.quoteReplacement()
  • 要被replace的文本包括$ 1

最后不会放1。 它将查找第一个匹配组的search正则expression式,然后是子THAT。这就是$ 1,$ 2或$ 3在replace文本中的含义:匹配来自search模式的组。

我经常将长文本string插入.properties文件,然后从这些文件生成电子邮件主题和主体。 的确,这似乎是在Spring Framework中执行i18n的默认方式。 我将XML标记作为占位符放入string中,并使用replaceAll()在运行时用值replaceXML标记。

我遇到了一个问题,用户input一个美元符号的美元和美分。 replaceAll()窒息在它上面,下面显示在stracktrace:

 java.lang.IndexOutOfBoundsException: No group 3 at java.util.regex.Matcher.start(Matcher.java:374) at java.util.regex.Matcher.appendReplacement(Matcher.java:748) at java.util.regex.Matcher.replaceAll(Matcher.java:823) at java.lang.String.replaceAll(String.java:2201) 

在这种情况下,用户在其input的某个地方input了“$ 3”,而replaceAll()在search正则expression式中查找了第三个匹配组,找不到一个,然后呕吐。

鉴于:

 // "msg" is a string from a .properties file, containing "<userInput />" among other tags // "userInput" is a String containing the user's input 

更换

 msg = msg.replaceAll("<userInput \\/>", userInput); 

 msg = msg.replaceAll("<userInput \\/>", Matcher.quoteReplacement(userInput)); 

解决问题。 用户可以放入任何types的字符,包括美元符号,没有问题。 它的行为完全符合你的期望。

要有保护模式,您可以用“\\\\”replace所有符号,数字和字母除外。 之后,你可以在这个受保护的模式中join你的特殊符号,使这个模式不像愚蠢的引用文本,但是真的很像一个彭定康,但是你自己。 没有用户特殊符号。

 public class Test { public static void main(String[] args) { String str = "yz (111)"; String p1 = "xx (111)"; String p2 = ".* .* \\(111\\)"; p1 = escapeRE(p1); p1 = p1.replace("x", ".*"); System.out.println( p1 + "-->" + str.matches(p1) ); //.*\ .*\ \(111\)-->true System.out.println( p2 + "-->" + str.matches(p2) ); //.* .* \(111\)-->true } public static String escapeRE(String str) { //Pattern escaper = Pattern.compile("([^a-zA-z0-9])"); //return escaper.matcher(str).replaceAll("\\\\$1"); return str.replaceAll("([^a-zA-Z0-9])", "\\\\$1"); } } 

Pattern.quote(“blabla”)很好地工作。

Pattern.quote()很好地工作。 它用“ \ Q ”和“ \ E ”包围句子,如果确实转义了“\ Q”和“\ E”。 但是,如果你需要做一个真正的正则expression式转义(或自定义转义),你可以使用下面的代码:

 String someText = "Some/s/wText*/,**"; System.out.println(someText.replaceAll("[-\\[\\]{}()*+?.,\\\\\\\\^$|#\\\\s]", "\\\\$0")); 

这个方法返回: Some / \ s / wText * / \,**

代码和testing代码:

 String someText = "Some\\E/s/wText*/,**"; System.out.println("Pattern.quote: "+ Pattern.quote(someText)); System.out.println("Full escape: "+someText.replaceAll("[-\\[\\]{}()*+?.,\\\\\\\\^$|#\\\\s]", "\\\\$0"));