参考下面的问题 - String.replaceAll single backslashes with double backslashes
我写了一个测试程序,我发现在两种情况下结果都是正确的,无论我是否逃避反斜杠。这可能是因为 - \ t是可识别的Java String转义序列。 (尝试\ s,它会抱怨)。 - \ t在正则表达式中作为文字选项卡。 我有点不确定原因。
是否有关于在Java中转义正则表达式的一般准则。我认为使用两个反斜杠是正确的方法。
我仍然想知道你的意见。
public class TestDeleteMe {
public static void main(String args[]) {
System.out.println(System.currentTimeMillis());
String str1 = "a b"; //tab between a and b
//pattern - a and b with any number of spaces or tabs between
System.out.println("matches = " + str1.matches("^a[ \\t]*b$"));
System.out.println("matches = " + str1.matches("^a[ \t]*b$"));
}
}
答案 0 :(得分:9)
转义序列有两种解释:首先是Java编译器,然后是regexp引擎。当Java编译器看到两个斜杠时,它会用一个斜杠替换它们。当斜杠后面有t
时,Java会用一个选项卡替换它;当双斜杠后面有t
时,Java就不管它了。但是,因为两个斜杠已被单个斜杠替换,所以regexp引擎会看到\t
,并将其解释为选项卡。
我认为让正则表达式将\t
解释为选项卡(即在Java中编写"\\t"
)更简洁,因为它允许您在调试,日志记录等过程中以预期形式查看表达式如果将Pattern
与\t
转换为字符串,您将在正则表达式的中间看到一个制表符,并可能将其与其他空格混淆。使用\\t
的模式没有此问题:它们会向您显示带有单斜杠的\t
,告诉您它们匹配的空白类型。
答案 1 :(得分:6)
第一种形式\\t
将由模式类扩展为制表符char。
在构建模式之前,第二种形式\t
将由Java扩展为tab char。
最后,无论如何都会得到一个标签字符。
答案 2 :(得分:6)
是的,有一个关于转义的一般准则:Java源代码中的转义序列被Java编译器(或最终的某些预处理器)取代。编译器会抱怨它不知道的任何转义序列,例如\s
。为RegEx模式编写字符串文字时,编译器将照常处理此文字,并使用相应的字符替换所有转义序列。然后,当程序执行时,Pattern类编译输入String,也就是说,它将再次评估转义序列。 Pattern类将\s
知道为一个字符类,因此能够编译包含该类的模式。但是,您需要从不知道此转义序列的Java编译器中转义\s
。为此,您可以转义反斜杠,从而导致\\s
。
简而言之,您总是需要两次转义RegEx模式的字符类。如果要匹配反斜杠,则正确的模式为\\\\
,因为Java编译器会将其\\
设置为模式编译器将识别为转义反斜杠字符。
答案 3 :(得分:1)
使用org.apache.commons.lang3.StringEscapeUtils.unescapeJava(...),您可以转义大多数常见的spl.chars以及unicode字符(将unicode字符集转换为可读的常规字符)