Java是否有内置的方法来转义任意文本,以便它可以包含在正则表达式中?例如,如果我的用户输入"$ 5",我想在输入结束后完全匹配而不是"5".
从Java 1.5开始,是的:
Pattern.quote("$5");
在看到下面的例子之前,我Pattern.quote
和之间的区别Matcher.quoteReplacement
并不清楚
s.replaceFirst(Pattern.quote("text to replace"), Matcher.quoteReplacement("replacement text"));
回复可能为时已晚,但您也可以使用Pattern.LITERAL
,在格式化时会忽略所有特殊字符:
Pattern.compile(textToFormat, Pattern.LITERAL);
我想你所追求的是\Q$5\E
.另见Pattern.quote(s)
Java5中介绍的.
有关详细信息,请参见Pattern javadoc.
首先,如果
你使用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 "" among other tags // "userInput" is a String containing the user's input
更换
msg = msg.replaceAll("", userInput);
同
msg = msg.replaceAll("", Matcher.quoteReplacement(userInput));
解决了这个问题.用户可以放入任何类型的字符,包括美元符号,没有问题.它的表现完全符合您的预期.
要使用受保护的模式,您可以用"\\\\"替换所有符号,但数字和字母除外.之后,你可以在这个受保护的模式中添加你的特殊符号,使这个模式不像愚蠢的引用文本,但真的像一个模式,但你自己.没有用户特殊符号.
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"); } }