从技术上讲,任何奇数个反斜杠,如文档中所述。

>>> r'\'
  File "<stdin>", line 1
    r'\'
       ^
SyntaxError: EOL while scanning string literal
>>> r'\\'
'\\\\'
>>> r'\\\'
  File "<stdin>", line 1
    r'\\\'
         ^
SyntaxError: EOL while scanning string literal

解析器似乎只能将原始字符串中的反斜杠视为常规字符(原始字符串不就是这样吗?),但我可能忽略了一些明显的东西。


当前回答

原因在这一节中用粗体标出的部分解释了:

String quotes can be escaped with a backslash, but the backslash remains in the string; for example, r"\"" is a valid string literal consisting of two characters: a backslash and a double quote; r"\" is not a valid string literal (even a raw string cannot end in an odd number of backslashes). Specifically, a raw string cannot end in a single backslash (since the backslash would escape the following quote character). Note also that a single backslash followed by a newline is interpreted as those two characters as part of the string, not as a line continuation.

原始字符串不是100%原始的,仍然有一些基本的反斜杠处理。

其他回答

另一位后来删除了他们的答案的用户(不确定他们是否愿意被归功于自己)建议,Python语言设计人员可以使用相同的解析规则,并在事后将转义字符扩展为原始形式(如果文字被标记为原始),从而简化解析器设计。

我认为这是一个有趣的想法,并将其作为社区维基供子孙后代使用。

事情就是这样!我认为这是python中的一个小缺陷!

我不认为这有什么好的理由,但这绝对不是解析;用\作为最后一个字符解析原始字符串非常容易。

问题是,如果您允许\是原始字符串中的最后一个字符,那么您将无法在原始字符串中放入"。python似乎使用了允许“而不是允许\作为最后一个字符。

不过,这应该不会造成任何麻烦。

如果你担心不能轻松地编写windows文件夹路径,例如c:\mypath\,那么不用担心,因为,你可以将它们表示为r" c:\mypath ",并且,如果你需要附加子目录名称,不要用字符串连接,因为这不是正确的方式来做它!使用os.path.join

>>> import os
>>> os.path.join(r"C:\mypath", "subfolder")
'C:\\mypath\\subfolder'

关于python原始字符串的所有误解是,大多数人认为反斜杠(在原始字符串中)只是一个普通字符。事实并非如此。理解这段python教程的关键是:

当有'r'或'r'前缀时,字母a 反斜杠包含在字符串中而不更改,并且所有 反斜杠留在字符串中

所以任何跟在反斜杠后面的字符都是原始字符串的一部分。一旦解析器输入一个原始字符串(非Unicode字符串)并遇到一个反斜杠,它就知道有两个字符(一个反斜杠和后面的一个字符)。

这种方式:

R 'abc\d'由a, b, c, \, d组成 R 'abc 'd'由a, b, c, \, ', d组成 R 'abc\ "由a, b, c, \, '组成

and:

R 'abc\'由a, b, c, \组成,'但现在没有终止引号了。

最后一个案例表明,根据文档,现在一个解析器无法找到结束引号,因为你看到上面的最后一个引号是字符串的一部分,即反斜杠不能在这里最后,因为它将“吞噬”字符串结束字符。

原始字符串

原始字符串的简单想法是

如果我在一对引号前加上r, 我可以在引号中间加任何我想加的 它意味着它自己。

不幸的是,这行不通,因为如果 恰好包含引号,原始字符串将在此结束。

我根本不可能把"我想要什么" 在固定的分隔符之间,因为其中一些可能看起来像 终止分隔符——无论该分隔符是什么。

真实世界的原始字符串(变体1)

解决这个问题的一个可能的方法是说

如果我在一对引号前加上r, 我可以在引号中间加任何我想加的 只要它不包含报价 它意味着它自己。

这种限制听起来很严厉,直到人们认识到这一点 Python提供的大量引用可以适应大多数情况 用这个规则。以下都是有效的Python引用:

'
"
'''
"""

分隔符有这么多的可能性,几乎什么都有 可以使之发挥作用。 唯一的例外是如果字符串 字面应该包含所有允许的完整列表 Python引号。

真实世界的原始字符串(变体2,如在Python中)

然而,Python采用了不同的路径,使用 以上规则的扩展版本。 它有效地说明了

如果我在一对引号前加上r, 我可以在引号中间加任何我想加的 只要它不包含报价 它意味着它自己。 如果我坚持要引用一段话,即使这是允许的, 但我必须在它前面加一个反斜杠。

因此,在某种意义上,Python方法更加自由 比上面的变体1 -但它有副作用 "mis"将闭引号解释为字符串的一部分 如果字符串的最后一个字符是反斜杠。

变体2没有帮助:

如果我想在字符串中引用, 但不是反斜杠,是我的字符串字面量的允许版本 都不是我所需要的 然而,鉴于我有三种不同的其他类型的引用 在我的支配下,我可能会选择其中一个,然后我的 问题就解决了,所以这不是问题。 有问题的情况是这样的: 如果我想让我的字符串以反斜杠结束,我就不知所措了。 我需要诉诸于连接一个非原始字符串文字 包含反斜杠。

结论

写完这篇文章后,我和其他几张海报一起去了 这种变体本来更容易理解和接受 因此更加python化。这就是生活!

尽管它的作用,即使是原始字符串也不能以单个结尾 反斜杠,因为反斜杠转义了下面的引号 字符—您仍然必须转义周围的引号字符到 将它嵌入到字符串中。也就是r"…“不是一个有效的字符串 字面量——原始字符串不能以奇数个反斜杠结尾。 如果需要用一个反斜杠结束原始字符串,可以使用 两个,切掉第二个。