2012-02-02 94 views
10

参照下面的问题 - String.replaceAll single backslashes with double backslashesJava中,正则表达式,需要转义反斜线在正则表达式

我写了一个测试程序,我发现结果是在这两种情况下都是这样,我是否转义反斜线或不。这可能是因为 - \ t是一个公认的Java String转义序列。 (试试吧,它会抱怨)。 - \ 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$")); 
    } 
} 

回答

6

第一种形式\\t将被模式类扩展为tab char。

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

最后,你得到一个选项卡字符的方式。

+5

这是正确的,*“我相信”*没有必要。 ''\\ t“'转换为Java字符串中的'”\ t“',这转换为正则表达式引擎中的制表符。 '“\ t”转换为Java字符串中的制表符,在正则表达式中保持不变。 – Tomalak 2012-02-02 13:53:03

+0

谢谢。我明白。 – RuntimeException 2012-02-02 13:53:03

+0

@Tomalak摆脱了'我相信'一点......对不起... – 2012-02-02 13:55:40

9

转义序列有两种解释:第一种是Java编译器,然后是正则表达式引擎。当Java编译器看到两个斜杠时,它会用一个斜杠替换它们。当斜线后面有t时,Java会用选项卡替换它;当双斜线后面有一个t时,Java将它留下。但是,由于两个斜杠已被替换为单斜杠,因此正则表达式引擎会看到\t,并将其解释为选项卡。

我认为这是更清洁,让正则表达式解释\t作为一个标签(即用Java编写"\\t"),因为它可以让你看到调试,记录等过程中其预期的形式表达如果转换Pattern\t字符串,你会在正则表达式的中间看到一个制表符,并且可能会把它混淆为其他空格。使用\\t的模式没有这个问题:他们会用一个斜杠告诉你一个\t,告诉你它们匹配的空白。

+1

谢谢。现在我明白,正则表达式引擎能够理解'[\ t]'(\ t在空格之后)和'[]'(空格之后的制表符)并对它们进行相同的处理。你认为我说得对吗? '[\ t]'虽然看起来更容易理解。所以我必须在Java中使用'[\\ t]'。 – RuntimeException 2012-02-02 14:05:38

+0

@SatishMotwani“必须”一词太强大了,但让'\\ t'流向正则表达式是一种很好的做法。 – dasblinkenlight 2012-02-02 14:07:25

6

是的,有关于转义的一般指导原则:Java源代码中的转义序列被Java编译器(或最终的某个预处理器)取代。编译器会抱怨它不知道的任何转义序列,例如\s。当您为RegEx模式编写字符串文字时,编译器将像往常一样处理该文字,并将所有转义序列替换为相应的字符。然后,程序执行时,Pattern类会编译输入的字符串,也就是说,它会再次计算转义序列。 Pattern类知道\s是一个字符类,因此可以编译一个包含这个类的模式。但是,您需要从不知道此转义序列的Java编译器中跳出\s。要做到这一点,您可以避开导致\\s的反斜杠。

总之,您总是需要为RegEx模式转义字符类两次。如果要匹配反斜杠,则正确的模式为\\\\,因为Java编译器会将其编译为\\,模式编译器会将其识别为转义的反斜杠字符。

+0

谢谢。我明白。所以你需要在Java中编写你的'String',以便Pattern引擎获得它所期望的。我想在将来用Java编写正则表达式时我必须非常小心。 – RuntimeException 2012-02-02 13:57:03

0

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