Answers:
Pattern.quote("$5");
"mouse".toUpperCase().replaceAll("OUS","ic")
,它将返回MicE
。你我就不会希望它返回MICE
,因为你没有申请toUpperCase()
上ic
。在我的示例中,quote()
也将其应用于插入.*
项replaceAll()
。您必须做其他事情,也许.replaceAll("*","\\E.*\\Q")
会行得通,但这是违反直觉的。
*.wav
变成regex模式\*\.wav
,而replaceAll会将其变成\.*\.wav
,这意味着匹配文件,其名称由任意数量的句点后跟组成.wav
。replaceAll("\\*", ".*")
如果它们采用了更加脆弱的实现方式,而这种实现方式依赖于识别所有可能的活动正则表达式字符并逐个转义,那么您最有可能需要……会那么容易吗?
在我看到以下示例之前,Pattern.quote
和之间的区别Matcher.quoteReplacement
对我尚不清楚
s.replaceFirst(Pattern.quote("text to replace"),
Matcher.quoteReplacement("replacement text"));
Pattern.quote
替换正则表达式搜索字符串中的特殊字符,如。| +()等,并Matcher.quoteReplacement
替换替换字符串中的特殊字符,如\ 1作为反向引用。
quoteReplacement
只关心两个符号$
,\
例如可以在替换字符串中用作反向引用$1
或\1
。因此,不得将其用于转义/引用正则表达式。
$Group$
有T$UYO$HI
。该$
标志为特殊的无论是在模式和替换:"$Group$ Members".replaceFirst(Pattern.quote("$Group$"), Matcher.quoteReplacement("T$UYO$HI"))
我想你所追求的是\Q$5\E
。另请参见Pattern.quote(s)
Java5中介绍的内容。
有关详细信息,请参见模式 javadoc。
首先,如果
它不会以1结尾。它将查看第一个匹配组和子THAT in的搜索正则表达式。这就是$ 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));
解决了问题。用户可以输入任何种类的字符,包括美元符号,而不会出现问题。它的行为完全符合您的期望。
要获得受保护的模式,可以将所有符号替换为“ \\\\”,数字和字母除外。然后,您可以在该受保护的模式中添加特殊符号,以使该模式不像愚蠢的引用文本那样工作,而实际上像木套纸,而是您自己的样式。没有用户特殊符号。
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");
}
}
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"));
\Q
and进行包装\E
。这可能会导致意外的结果,例如,可能Pattern.quote("*.wav").replaceAll("*",".*")
会导致\Q.*.wav\E
和.*\.wav
,而不是您期望的那样。