如何在Java中转义正则表达式的文本

时间:2008-09-12 23:36:37

标签: java regex escaping

Java是否有内置的方法来转义任意文本,以便它可以包含在正则表达式中?例如,如果我的用户输入“$ 5”,我想在输入结束后完全匹配而不是“5”。

8 个答案:

答案 0 :(得分:422)

Java 1.5, yes

Pattern.quote("$5");

答案 1 :(得分:101)

在我看到以下示例之前,Pattern.quoteMatcher.quoteReplacement之间的差异并不明确

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

答案 2 :(得分:26)

回复可能为时已晚,但您也可以使用Pattern.LITERAL,这会在格式化时忽略所有特殊字符:

Pattern.compile(textToFormat, Pattern.LITERAL);

答案 3 :(得分:13)

我认为你所追求的是\Q$5\E。另请参阅Java5中引入的Pattern.quote(s)

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

答案 4 :(得分:10)

首先,如果

  • 您使用replaceAll()
  • 你不要使用Matcher.quoteReplacement()
  • 要替换的文字包括$ 1

最后不会放1。它将查看第一个匹配组和子THAT的搜索正则表达式。这就是替换文本中$ 1,$ 2或$ 3的含义:匹配搜索模式中的组。

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

我遇到了一个问题,用户输入一个美元符号的美元和美分数字。 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)

在这种情况下,用户在输入中的某处输入了“$ 3”,并且replaceAll()在搜索正则表达式中查找第三个匹配组,没有找到,并且puked。

假设:

// "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));

解决了这个问题。用户可以放入任何类型的字符,包括美元符号,没有问题。它的表现完全符合您的预期。

答案 5 :(得分:6)

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

public class Test {
    public static void main(String[] args) {
        String str = "y z (111)";
        String p1 = "x x (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");
    }
}

答案 6 :(得分:3)

Pattern.quote(&#34; blabla&#34;)效果很好。

Pattern.quote()效果很好。它用句子&#34; \ Q &#34;括起句子。和&#34; \ E &#34;,如果它确实逃脱&#34; \ Q&#34;和&#34; \ E&#34;。 但是,如果您需要进行真正的正则表达式转义(或自定义转义),您可以使用以下代码:

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

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

代码和测试代码:

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

答案 7 :(得分:-1)

^(否定)符号用于匹配字符组中不存在的字符。

这是指向Regular Expressions

的链接

以下是有关否定的图像信息:

Info about negation