与Java和Python一样,Perl具有\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在处理\\
时授权""
。除了有点混乱,它只是凌乱。所以,我认为这个决定有充分的理由。谁知道为什么?
答案 0 :(得分: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的未知逃逸做出了不同的设计选择...据我所知,官方Design FAQ没有涉及到这一点,并且Guido没有直接解决。但我可以猜到。一般来说,Perl与C(以及Java与C ++)的最大兼容性作为许多领域的高优先级,其中Python更优先考虑对编程教师更直观的意义。这可能是其中一个方面。 (我怀疑如果今天从头开始重新设计Python,或者甚至在添加原始字符串时重新设计,它会出错。)