Java中的正则表达式:在正则表达式中需要转义反斜杠

16
关于下面的问题 - String.replaceAll single backslashes with double backslashes
我写了一个测试程序,发现无论我是否转义反斜杠,结果都是正确的。这可能是因为: - \t 是Java字符串转义序列。(尝试\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$")); 
  }
}
4个回答

10
是的,有一个关于转义的通用指南:Java源代码中的转义序列将被Java编译器(或某些预处理器)替换。编译器会抱怨它不认识的任何转义序列,例如\s。当您为RegEx模式编写字符串文字时,编译器将像往常一样处理此文字,并替换所有转义序列为相应的字符。然后,在程序执行时,Pattern类编译输入字符串,即它将再次评估转义序列。Pattern类知道\s作为一个字符类,因此能够编译包含这个类的模式。但是,您需要从不知道这个转义序列的Java编译器中转义\s。为此,您需要转义反斜杠,结果是\\s
简而言之,您总是需要两次转义正则表达式模式的字符类。如果您想匹配反斜杠,则正确的模式是\\\\,因为Java编译器会将其变成\\,而Pattern编译器将识别为转义的反斜杠字符。

谢谢。我明白了。所以你需要在Java中编写你的String,以便Pattern引擎得到它所期望的内容。我想我将来在Java中编写正则表达式时必须非常小心。 - RuntimeException

9
有两种解释转义序列: Java编译器和正则表达式引擎。当Java编译器看到两个斜杠时,它将它们替换为单个斜杠。当斜杠后面跟着t时,Java会将其替换为制表符;当双斜杠后面跟着t时,Java则不做处理。然而,由于两个斜杠被替换为单个斜杠,正则表达式引擎看到的是\t,并将其解释为一个制表符。
我认为更好的做法是让正则表达式引擎将\t解释为制表符(即在Java中编写"\\t"),因为这样可以在调试、日志记录等过程中以预期的形式查看表达式。如果你将带有\t的模式转换为字符串,你将在正则表达式的中间看到一个制表符,可能会将其误认为是其他空格符号。带有\\t的模式则没有这个问题:它们会显示一个单斜杠后跟着\t,告诉你它们匹配的确切空格符号类型。

1
谢谢。现在我明白了,正则表达式引擎可以理解[ \t](空格后跟制表符)和[ ](空格后跟制表符)并将它们处理为相同的内容。你认为我这样说是正确的吗?[ \t]看起来更易懂一些。所以我必须在Java中使用[ \\t] - RuntimeException
@SatishMotwani,“必须”这个词太强了,但是让\\t流到正则表达式中是一个好习惯。 - Sergey Kalinichenko

6

第一种形式\\t将被模式类扩展为制表符。

第二种形式\t将在Java构建模式之前被扩展为制表符。

最终,您无论哪种方式都会得到一个制表符。


5
没问题,*"我相信"*这句话是不必要的。在Java字符串中,"\\t"会被翻译成制表符\t,在正则表达式引擎中也会被视为制表符。而"\t"在Java字符串中就已经代表了制表符,在正则表达式中也不会改变。 - Tomalak

1
使用org.apache.commons.lang3.StringEscapeUtils.unescapeJava(...),您可以转义大多数常见的spl.chars和unicode字符(将unicode字符集转换为可读的常规字符)。

我曾试图用2或4个反斜杠来转义\*\d(以获取星号和数字),但没有成功。当我使用了4个反斜杠和StringEscapeUtils.unescapeJava时,它奏效了!这拯救了我的理智;谢谢。 - nikodaemus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接