【问题标题】:Why do 3 backslashes equal 4 in a Python string?为什么 Python 字符串中的 3 个反斜杠等于 4?
【发布时间】:2016-05-09 08:36:17
【问题描述】:

你能告诉我为什么'?\\\?'=='?\\\\?'True吗?这让我发疯,我找不到合理的答案......

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

【问题讨论】:

  • 后者没有转义任何东西,所以它最终被自己转义了
  • 不需要包含list() 甚至:>>> '?\\\?' '?\\\\?'
  • @PadraicCunningham 它并没有“最终自己逃脱”。这甚至意味着什么?
  • 有趣的是,它们都等于两个反斜杠:-)
  • @immibis,这正是正在发生的事情。你知道repr和str的区别吗?尝试在字符串中使用一个反斜杠打印两者,它可能会变得清晰

标签: python python-2.7


【解决方案1】:

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

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

(强调原文)

因此,在python中,并不是三个反斜杠等于四个,而是当你在反斜杠后面加上?这样的字符时,这两个字符一起作为两个字符出现,因为\?不是一个识别转义序列。

【讨论】:

  • 这与宽大相反。宽容是大多数人其他人的“如果你反斜杠不需要它的字符,反斜杠什么都不做”的行为。再加上另一个约定(反斜杠字母数字可能使它们特别,但反斜杠标点符号总是使它不特别),您可以获得非常好的属性,您可以通过反斜杠所有标点符号安全地去除字符串,而不必知道哪些字符是特别的interpeted — Python 缺乏的属性。
  • 不,宽松的反义词是在您使用无法识别的反斜杠转义时引发错误。 (几乎所有编译语言都会这样做。请记住,Python 的字符串处理基本上“像 C 语言,只是在处理无效的反斜杠转义时我们不会崩溃”)此外,在字符串中,无论是哪种语言,只有两个字符需要转义- 无论您使用什么作为分隔符和反斜杠本身。我不理解很难记住这两点的论点。
  • @DanielMartin 在某些语言中,分隔符用作它自己的转义字符(例如'escape''d')。您甚至不必记住那里的其他角色!
  • 哦等等,我猜标准帕斯卡也使用了那个系统 - 见nyx.net/~gthompso/self_pasc.txt
  • @DanielMartin SQL 也是。
【解决方案2】:

这是因为反斜杠充当紧随其后的字符的转义字符,如果组合表示有效的转义序列。十几个转义序列是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('?\\\\\\?')
?\\\?

或者您可能会发现“原始”字符串更容易理解:

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

这轮流对字符串文字进行转义序列处理。详情请见String Literals

【讨论】:

  • 你是对的'?\\\?'=='?\\?' 给了False,我打错了。如问题所示,应该是'?\\\?'=='?\\\\?',我已经更正了。
【解决方案3】:

因为\x 在字符串中,当x 不是nrt0 等特殊反斜杠字符之一时,计算结果为带有反斜杠的字符串然后是x

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

【讨论】:

    【解决方案4】:

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

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

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

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

    所以 '\\\\' 是 '\\' 后跟 '\\' 是 '\\' (两个转义 \)

    而 '\\\' 是 '\\' 后跟 '\' 也是 '\\' (一个转义的 \ 和一个原始的 \)

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

    所以 'String' 和 "String" 在 python 中是完全一样的东西,它们不影响转义序列的解释。

    【讨论】:

      【解决方案5】:

      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
      \\?
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-01-23
        • 1970-01-01
        • 2016-08-30
        • 1970-01-01
        • 1970-01-01
        • 2013-11-12
        相关资源
        最近更新 更多