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

lskq00tm  于 2023-01-15  发布在  Java
关注(0)|答案(8)|浏览(119)

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

4zcjmb1e

4zcjmb1e1#

从Java 1.5开始,是的:

Pattern.quote("$5");
7kqas0il

7kqas0il2#

在看到以下示例之前,我并不清楚Pattern.quoteMatcher.quoteReplacement之间的区别

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

ukxgm1gy3#

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

Pattern.compile(textToFormat, Pattern.LITERAL);
egmofgnx

egmofgnx4#

我认为你所追求的是\Q$5\E。另请参见Java5中引入的Pattern.quote(s)
有关详细信息,请参见Pattern javadoc。

yyhrrdl8

yyhrrdl85#

首先如果

  • 使用replaceAll()
  • 你不使用匹配器. quoteReplacement()
  • 中要替换的文本包含$1

它不会在末尾添加1,而是在搜索正则表达式中查找第一个匹配的组,并将THAT代入其中。这就是$1、$2或$3在替换文本中的含义:匹配来自搜索模式的组。
我经常将很长的文本字符串插入到. properties文件中,然后从中生成电子邮件主题和正文。实际上,这似乎是Spring Framework中执行i18n的默认方式。我将XML标记作为占位符放入字符串中,然后使用replaceAll()在运行时用值替换XML标记。
我遇到了一个问题,用户输入了一个美元和美分的数字,带有一个美元符号。replaceAll()卡住了,在tracktrace中显示了以下内容:

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

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

xeufq47z

xeufq47z6#

要有受保护的模式,你可以用“\\"替换所有的符号,除了数字和字母。然后你可以把你的特殊符号放进受保护的模式,使这个模式不像愚蠢的引用文本,而是真正像一个模式,而是你自己的。没有用户特殊符号。

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

nafvub8i7#

Pattern.quote(“blabla”)很好用。
Pattern.quote()很好用。它用字符“\Q”和“\E"将句子括起来,如果它确实转义了“\Q”和“\E”。但是,如果你需要进行真实的的正则表达式转义(或自定义转义),你可以使用下面的代码:

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

此方法返回:* 部分/\s/w文本 /\,**
示例和测试代码:

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

qyuhtwio8#

^(否定)符号用于匹配不在字符组中的内容。
这是指向Regular Expressions的链接
下面是关于否定的图像信息:

相关问题