Java正则表达式转义字符

3

在匹配某些特定字符(例如换行符)时,您可以使用正则表达式"\\n"或者直接使用"\n"。例如,以下代码将一个字符串拆分为多个行的数组:

String[] lines = allContent.split("\\r?\\n");

但是以下方式同样有效:

String[] lines = allContent.split("\r?\n");

我的问题:

上述两种方法是否完全相同,还是存在微小差异?如果有后者,请举例说明在哪些情况下会得到不同的结果。

或者仅在[可能/理论]性能方面有区别吗?


2
没有区别。\\n 匹配 LF,\n 也匹配 LF。 - Wiktor Stribiżew
2
如果您使用注释模式,那么应该会有所不同。 - Sebastian Proske
@SebastianProske 那是真的。我的意思是,鉴于当前的正则表达式,没有区别。如果使用 (?x),那么在 Java 正则表达式中应该转义空格字符。即使它们用在字符类中也是如此。 - Wiktor Stribiżew
在Java中,\\r代表两个字符:\ r,这在RegEx引擎中被解释为CR(回车)字符。另一方面,\r代表Java中的CR,并且直接传递给RegEx引擎。 - Usagi Miyamoto
2个回答

3
在当前的情况下没有区别。通常的字符串转义序列是通过一个反斜杠和一个有效的转义字符(如"\n""\r"等)形成的,而正则表达式转义序列是通过一个文字反斜杠(即Java字符串字面值中的双反斜杠)和一个有效的正则表达式转义字符(如"\\n""\\d"等)形成的。 "\n"(一个转义序列)是一个文字LF(换行符),而"\\n"是一个正则表达式转义序列,用于匹配LF符号。 "\r"(一个转义序列)是一个文字CR(回车符),而"\\r"是一个正则表达式转义序列,用于匹配CR符号。 "\t"(一个转义序列)是一个制表符文字,而"\\t"是一个正则表达式转义序列,用于匹配制表符文字。
请参见Java regex docs中支持的正则表达式转义符列表。
但是,如果你使用Pattern.COMMENTS标志(用于引入注释和格式化模式,使正则表达式引擎忽略模式中的所有未转义空格),你需要使用"\\n""\\\n"来定义Java字符串文字中的换行符(LF),并使用"\\r""\\\r"来定义回车符(CR)。
参见Java测试
String s = "\n";
System.out.println(s.replaceAll("\n", "LF")); // => LF
System.out.println(s.replaceAll("\\n", "LF")); // => LF
System.out.println(s.replaceAll("(?x)\\n", "LF")); // => LF
System.out.println(s.replaceAll("(?x)\\\n", "LF")); // => LF
System.out.println(s.replaceAll("(?x)\n", "<LF>")); 
// => <LF>
//<LF>

为什么最后一个会产生<LF>+换行+<LF>?因为"(?x)\n"等于"",也就是一个空模式,在换行符前后匹配了一个空格。


0

是的,它们是不同的。Java编译器在《Java语言规范》第3.3节中对Unicode转义有不同的行为;

Java编程语言规定了一种标准的方式,将Unicode编写的程序转换为ASCII,从而将程序转换为可以由基于ASCII的工具处理的形式。该转换涉及将程序源文本中的任何Unicode转义序列转换为ASCII,方法是在每个转义序列前添加一个额外的u - 例如,\uxxxx变成\uuxxxx - 同时将源文本中的非ASCII字符转换为包含单个u的Unicode转义序列。

那么这如何影响Java Doc中的/n与//n

因此,在表示正则表达式的字符串文字中必须加倍反斜杠,以保护它们免受Java字节码编译器的解释。

以下是相同文档的示例:

例如,字符串字面量"\b"在正则表达式中解释时匹配一个后退字符,而"\b"则匹配单词边界。字符串字面量"(hello)"是非法的,并导致编译时错误;为了匹配字符串(hello),必须使用字符串字面量"\(hello\)"。

1
您正在解释在Java字符串文字中使用“\”来定义单个反斜杠的必要性。 OP的问题是“\n”和“\n”是否匹配相同的字符串。虽然模式不同,但它们匹配相同的文本。这就是为什么我说在当前情况下没有区别 - Wiktor Stribiżew
是的,你的答案是正确的,我只是想知道它们之间的区别。在某些情况下,会有不同的结果,在其他情况下则会有相同的结果。 - Gatusko

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