Skip to main content
 首页 » 编程设计

java之用双引号封装时转义序列与预定义字符类(也称为特殊正则表达式字符)

2025年05月04日31myhome

Perl 与 Java 和 Python 一样,除了其他特殊字符外,还有 \s,即匹配空白的特殊正则表达式字符。

在 Perl 中,以下内容无效:

my $sentence = "The End"; 
my $subStr = "\s"; #Does NOT work, needs to be "\\s" or '\s' 
 
if ($sentence =~ /$subStr/) 
{ 
    say "True"; 
} 

在 Java 中,这是有效的:

String s = "The End"; 
 
if (s.matches(".*\\s.*")) //same deal as with Perl ("\\s") 
{ 
    System.out.println("True"); 
} 

在 Python 中,可以使用 "\s" 或 '\s'。

Java 和 Perl 似乎都以相同的方式处理由 "" 封装的特殊正则表达式字符。我查了一下Predefined Character Classes (Java),它只是说:“如果您在字符串文字中使用转义构造,则必须在反斜杠之前加上另一个反斜杠,以便编译字符串。”

为什么 Java 和 Perl 对转义序列的处理方式不同于特殊的正则表达式字符(当它们都被 "" 封装时),而 python 却没有?

为什么设计者选择转义序列,如 \n 或 \t,要求一个反斜杠,但对于预定义的字符类,如 \s,需要两个(在 "" 中)?

这是其他原因造成的吗?或者它是否以某种方式简化了某种交互或者你有什么?

我假设这不是任意的。 Python 只需要 \ 两种方式,但 Perl 和 Java 在处理 "" 时强制要求 \\。除了有点困惑之外,它只是一团糟。所以,我认为这个决定有充分的理由。有人知道为什么吗?

请您参考如下方法:

Java、Perl 和 Python 都使用 C 风格的反斜杠进行转义。正则表达式还使用 C 风格的反斜杠进行转义。这会导致所有三种语言出现问题——事实上,对于许多其他语言也是如此。

例如,所有三种语言都会将 '\\' 转换为单个反斜杠,将 '\n' 转换为换行符等,然后才能到达正则表达式编译器。

唯一的区别是在 Python 中,未知的转义序列如 '\s' 解析为它们自己,而在 Java 和 Perl 中它们解析为 's'。所以,在 Python 中,虽然你需要 '\\\n',但你不需要 '\\s',而在 Java 和 Perl 中,你需要转义两者的反斜杠。

有些语言会做出第三种选择,将未知的转义序列视为错误。


因此,如果您记住了已知转义的列表,有时您可以在 Python 中不转义反斜杠而逃脱。但你真的不应该。

为什么不呢?因为,即使您完全确定自己已经记住了转义序列,您真的想让任何想要阅读(或维护)您的代码的人都必须这样做吗?当我看到 "abc\\sdef" 或 r"abc\sdef" 时,我立即明白了它的确切含义。当我看到未转义的 "abc\sdef" 时,我认为我知道,但我可能错了,我必须去查找或在解释器中尝试找出来。


正确的做法是转义反斜杠,或使用适合您语言的原始字符串或正则表达式语法。


如果您想知道为什么 Python 为 Perl 和 Java 的未知转义做出了不同的设计选择……据我所知,这在官方 Design FAQ 中没有涉及。 Guido 还没有直接解决这个问题。但我能猜到。总的来说,Perl 将与 C 的最大兼容性(以及 Java 与 C++)作为许多领域的高优先级,而 Python 更优先考虑对编程教师更直观的理解。这可能是这些领域之一。 (我怀疑如果 Python 今天是从头开始重新设计的,或者甚至在添加原始字符串时重新设计,它也会出现错误。)