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


当前回答

Pattern.quote("blabla")工作得很好。

Pattern.quote()工作得很好。它用字符“\Q”和“\E”包围句子,如果它转义了“\Q”和“\E”。 然而,如果你需要做一个真正的正则表达式转义(或自定义转义),你可以使用以下代码:

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

其他回答

若要保护图案,可将除数字和字母外的所有符号替换为“\\\\”。之后,你可以在受保护的模式中加入你的特殊符号,使这个模式不像愚蠢的引用文本,而是真正像一个模式,但你自己的。无用户专用符号。

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

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

这是正则表达式的链接

下面是关于否定的图片信息:

首先,如果

你使用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()在搜索正则表达式中寻找第三个匹配组,但没有找到,于是吐了出来。

考虑到:

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

解决了问题。用户可以毫无问题地输入任何类型的字符,包括美元符号。它的表现完全符合你的预期。

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

Pattern.compile(textToFormat, Pattern.LITERAL);

Pattern.quote("blabla")工作得很好。

Pattern.quote()工作得很好。它用字符“\Q”和“\E”包围句子,如果它转义了“\Q”和“\E”。 然而,如果你需要做一个真正的正则表达式转义(或自定义转义),你可以使用以下代码:

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