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

Ste*_* P. 1 python java regex perl

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";
}
Run Code Online (Sandbox Code Playgroud)

在Java中,这将是有效的:

String s = "The End";

if (s.matches(".*\\s.*")) //same deal as with Perl ("\\s")
{
    System.out.println("True");
}
Run Code Online (Sandbox Code Playgroud)

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

Java和Perl似乎都在处理由""它封装的特殊正则表达式字符.我查找了预定义字符类(Java),它简单地说:"如果在字符串文字中使用转义构造,则必须在反斜杠前面加上另一个反斜杠才能编译字符串."

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

就像为什么设计师选择转义序列一样,\n或者\t,要求一个反斜杠,但是对于预定义的字符类,比如\s要求两个(同时"")?

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

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

aba*_*ert 8

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的未知转义做出了不同的设计选择......据我所知,官方设计常见问题解答并没有涵盖这一点,而Guido没有直接解决这个问题.但我可以猜到.一般来说,Perl与C(以及Java与C++)的最大兼容性在许多领域都是高优先级,其中Python更优先考虑对编程教师更直观的意义.这可能是其中一个方面.(我怀疑如果今天从头开始重新设计Python,或者甚至在添加原始字符串时再回过头来,它会出错.)