为什么Python字符串中的3个反斜杠等于4?

时间:2016-02-01 00:25:21

标签: python python-2.7

你能告诉我'?\\\?'=='?\\\\?'给出True的原因吗?这让我发疯,我找不到合理的答案......

>>> list('?\\\?')
['?', '\\', '\\', '?']
>>> list('?\\\\?')
['?', '\\', '\\', '?']

5 个答案:

答案 0 :(得分:84)

基本上,因为python在反斜杠处理方面略显宽松。引自https://docs.python.org/2.0/ref/strings.html

  

与标准C不同,所有未识别的转义序列都保留在字符串中不变,即反斜杠保留在字符串中。

(原文强调)

因此,在python中,并不是三个反斜杠等于四,当你用?之类的字符跟随反斜杠时,两个一起作为两个字符出现,因为\?不是可识别的转义序列。

答案 1 :(得分:30)

这是因为如果组合表示有效的转义序列,则反斜杠将作为紧随其后的字符的转义字符。十几个转义序列是listed here。它们包括明显的内容,例如换行符\n,水平标签\t,回车\r以及更加模糊的内容,例如使用\N{...}命名的unicode字符,例如\N{WAVY DASH}代表unicode字符\u3030。关键的一点是,如果转义序列未知,则字符序列将保留在字符串中。

部分问题也可能是Python解释器输出误导了你。这是因为反斜杠在显示时会被转义。但是,如果您打印这些字符串,您将看到额外的反斜杠消失。

>>> '?\\\?'
'?\\\\?'
>>> print('?\\\?')
?\\?
>>> '?\\\?' == '?\\?'    # I don't know why you think this is True???
False
>>> '?\\\?' == r'?\\?'   # but if you use a raw string for '?\\?'
True
>>> '?\\\\?' == '?\\\?'  # this is the same string... see below
True

对于您的具体示例,在第一种情况'?\\\?'中,第一个\转义第二个反斜杠,留下一个反斜杠,但第三个反斜杠仍然是反斜杠,因为\?不是一个有效的转义序列。因此,结果字符串为?\\?

对于第二种情况'?\\\\?',第一个反斜杠转义第二个,第三个反斜杠转义第四个转义,导致字符串?\\?

这就是为什么三个反斜杠与四个相同的原因:

>>> '?\\\?' == '?\\\\?'
True

如果要创建一个包含3个反斜杠的字符串,则可以转义每个反斜杠:

>>> '?\\\\\\?'
'?\\\\\\?'
>>> print('?\\\\\\?')
?\\\?

或者您可能会发现" raw"字符串更容易理解:

>>> r'?\\\?'
'?\\\\\\?'
>>> print(r'?\\\?')
?\\\?

这转换为字符串文字的转义序列处理。有关详细信息,请参阅String Literals

答案 2 :(得分:13)

由于\x字符串中的xn不是rt0,{{1}等特殊可反映字符之一等等,计算为带反斜杠的字符串,然后是x

>>> '\?'
'\\?'

答案 3 :(得分:7)

来自字符串文字下的python词法分析页面: https://docs.python.org/2/reference/lexical_analysis.html

有一个表格列出了所有已识别的转义序列。

\\是一个转义序列,它是=== \

\?不是转义序列而是=== \?

所以' \\\\'是' \\'接着是' \\'这是' \\' (两个逃脱\)

和' \\\'是' \\'其次是' \'这也是' \\' (一个逃脱\和一个原始\)

另外,应该注意的是,与其他语言不同,python不区分字符串文字的单引号和双引号。

所以' String'和"字符串"在python中是完全相同的,它们不会影响转义序列的解释。

答案 4 :(得分:1)

mhawke的答案几乎涵盖了它,我只想以更简洁的形式重述它,并用最少的例子来说明这种行为。

我想要添加的一件事是,转义处理从左向右移动,以便\n首先找到反斜杠,然后查找要转义的字符,然后找到n并将其转义; \\n找到第一个反斜杠,找到第二个并转义它,然后找到n并将其视为文字n; \?找到反斜杠并查找要转义的字符,查找无法转义的?,并将\视为字面反斜杠。

正如mhawke所说,关键在于交互式解释器在显示字符串时会逃避反斜杠。我猜这是为了确保从解释器复制到代码编辑器的文本字符串是有效的python字符串。但是,在这种情况下,为方便起见,这种容差会导致混淆。

>>> print('\?') # \? is not a valid escape code so backslash is left as-is
\?
>>> print('\\?') # \\ is a valid escape code, resulting in a single backslash
'\?'

>>> '\?' # same as first example except that interactive interpreter escapes the backslash
\\?
>>> '\\?' # same as second example, backslash is again escaped
\\?