如何在Java中为正则表达式转义文本
Java是否有一种内置的方法来转义任意文本,以便可以将其包含在正则表达式中?例如,如果我的用户输入“$5”,我希望精确匹配它,而不是在输入结束后输入“5”。因为:如何在Java中为正则表达式转义文本,java,regex,escaping,Java,Regex,Escaping,Java是否有一种内置的方法来转义任意文本,以便可以将其包含在正则表达式中?例如,如果我的用户输入“$5”,我希望精确匹配它,而不是在输入结束后输入“5”。因为: 我想你想要的是\Q$5\E。另请参见Java5中引入的Pattern.quote 有关详细信息,请参见javadoc。在看到以下示例之前,我并不清楚和之间的区别 s.replaceFirst(Pattern.quote("text to replace"), Matcher.quoteReplaceme
我想你想要的是
\Q$5\E
。另请参见Java5中引入的Pattern.quote
有关详细信息,请参见javadoc。在看到以下示例之前,我并不清楚和之间的区别
s.replaceFirst(Pattern.quote("text to replace"),
Matcher.quoteReplacement("replacement text"));
首先,如果
- 您使用replaceAll()
- 您不使用Matcher.quoteReplacement()
- 待替换的文本包括$1
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”是.properties文件中的字符串,其中包含“”和其他标记
//“userInput”是包含用户输入的字符串
替换
msg = msg.replaceAll("<userInput \\/>", userInput);
msg=msg.replaceAll(“,用户输入);
与
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");
}
}
响应可能太晚了,但您也可以使用
Pattern.LITERAL
,这将在格式化时忽略所有特殊字符:
Pattern.compile(textToFormat, Pattern.LITERAL);
模式。引号(“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"));
^(否定)符号用于匹配不在字符组中的内容
这是到的链接
以下是有关否定的图像信息:
我很好奇这和使用文字标志之间是否有什么区别,因为javadoc说没有嵌入式标志来打开和关闭文字:请注意,只有知道您的输入,才可以使用\Q和\E。Pattern.quote还将处理文本实际包含这些序列的情况。特别是,
Pattern.quote
替换正则表达式搜索字符串中的特殊字符,如.|+()等,以及Matcher.quoteReplacement
替换替换字符串中的特殊字符,如用于反向引用的\1。我不同意。Pattern.quote用\Q和\E包装其参数。它不会转义特殊字符。Matcher.quoteReplacement(“4$&%$”)生成“4\$&%\$”。它转义特殊字符。换句话说:quoteReplacement
只关心两个符号$
和\
,例如,这两个符号可以在替换字符串中用作反向引用$1
或\1
。因此,它不能用于转义/引用regex.Awesome。下面是一个示例,我们想用T$UYO$HI
替换$Group$
。$
符号在模式和替换中都是特殊的:“$Group$Members.replaceFirst(模式.quote($Group$”),Matcher.quoteReplacement(“T$UYO$HI”)
请注意,这不会转义字符串本身,而是使用\Q
和\E
对其进行包装。这可能会导致意外的结果,例如Pattern.quote(*.wav”)。replaceAll(“*”,“*”)
将导致\Q.*.wav\E
,而不是像您可能期望的那样.*.wav
。我只是想指出,这种转义方法也适用于您随后引入的表达式。这可能令人惊讶。如果执行鼠标.toUpperCase().replaceAll(“OUS”,“ic”)
操作,它将返回鼠标
。您不会期望它返回鼠标
,因为您没有在ic
上应用toUpperCase()
。在我的示例中,replaceAll()
也将quote()
应用于*
插入。您必须执行其他操作,可能.replaceAll(“*”,“\\E.*\\Q”)
会起作用,但这是违反直觉的。@Parameleon:解决相应问题的最佳方法是使用split map mkString方法。.wav.split(“\\”).map(Pattern.quote).mkString(“.”)。r@Paramaleon如果它确实通过添加单个转义来工作,那么您的初始示例仍然无法实现您想要的功能…如果它单独转义字符,它将把*.wav
转换为正则表达式模式\*\.wav
,而replaceAll将把它转换为\.\.wav
,这意味着它将匹配名称由任意数量的句点加上.wav
组成的文件。如果他们使用了更脆弱的relie实现,那么您很可能需要replaceAll(“\\*”,“*”)
String someText = "Some/s/wText*/,**";
System.out.println(someText.replaceAll("[-\\[\\]{}()*+?.,\\\\\\\\^$|#\\\\s]", "\\\\$0"));
String someText = "Some\\E/s/wText*/,**";
System.out.println("Pattern.quote: "+ Pattern.quote(someText));
System.out.println("Full escape: "+someText.replaceAll("[-\\[\\]{}()*+?.,\\\\\\\\^$|#\\\\s]", "\\\\$0"));