1

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 似乎都处理""相同封装的特殊正则表达式字符。我查找了预定义字符类(Java),它简单地说:“如果您在字符串文字中使用转义构造,则必须在反斜杠前面加上另一个反斜杠才能编译字符串。”

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

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

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

我会假设这不是任意的。Python 只需要\任何一种方式,但 Perl 和 Java\\在处理"". 除了有点混乱之外,它只是混乱。所以,我认为这个决定是有充分理由的。有谁知道为什么?

4

1 回答 1

8

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

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

唯一的区别是,在 Python 中,未知转义序列(如'\s'解析为自身),而在 Java 和 Perl 中,它们解析为's'. 因此,在 Python 中,虽然需要'\\\n',但不需要'\\s',而在 Java 和 Perl 中,您需要转义两者的反斜杠。

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


所以,如果你记住了已知转义的列表,你有时可以避免在 Python 中不转义反斜杠。但你真的不应该。

为什么不?因为,即使你绝对确定你已经记住了转义序列,你真的想让任何想要阅读(或维护)你的代码的人都需要这样做吗?当我看到"abc\\sdef"orr"abc\sdef"时,我立即确切地知道它的含义。当我看到 unescaped"abc\sdef"时,我我知道,但我可能是错的,我必须去查找它或在解释器中尝试以找出答案。


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


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

于 2013-06-06T22:42:55.767 回答