222

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

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

似乎解析器可以将原始字符串中的反斜杠视为常规字符(这不是原始字符串的全部内容吗?),但我可能遗漏了一些明显的东西。

4

12 回答 12

149

关于 python 的原始字符串的全部误解是,大多数人认为反斜杠(在原始字符串中)和其他所有字符一样只是一个常规字符。它不是。理解的关键是这个python的教程序列:

当存在 ' r ' 或 ' R ' 前缀时,反斜杠后面的字符将原样包含在字符串中,并且所有反斜杠都保留在字符串中

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

这边走:

r'abc\d'包括a, b, c, \, d

r'abc\'d'包括a, b, c, \, ', d

r'abc\''包括a, b, c, \, '

和:

r'abc\'包含a, b, c, \, '但现在没有终止引号。

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

于 2013-10-29T09:24:45.133 回答
148

原因在我以粗体突出显示的那部分的部分中进行了解释:

字符串引号可以用反斜杠转义,但反斜杠保留在字符串中;例如,r"\""是由两个字符组成的有效字符串文字:反斜杠和双引号;r"\"不是有效的字符串文字(即使是原始字符串也不能以奇数个反斜杠结尾)。具体来说,原始字符串不能以单个反斜杠结尾(因为反斜杠会转义后面的引号字符)。另请注意,后跟换行符的单个反斜杠被解释为这两个字符作为字符串的一部分,而不是作为续行符。

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

于 2009-03-15T13:05:31.097 回答
28

它就是这样儿的!我认为它是 python 中的小缺陷之一!

我认为没有充分的理由,但绝对不是解析;用 \ 作为最后一个字符来解析原始字符串真的很容易。

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

但是,这不应该造成任何麻烦。

如果您担心无法轻松编写 windows 文件夹路径,例如,c:\mypath\请不要担心,因为,您可以将它们表示为r"C:\mypath",并且,如果您需要附加子目录名称,请不要使用字符串连接,因为无论如何,这不是正确的方法!采用os.path.join

>>> import os
>>> os.path.join(r"C:\mypath", "subfolder")
'C:\\mypath\\subfolder'
于 2009-03-15T13:17:10.117 回答
23

为了让你用斜杠结束原始字符串,我建议你可以使用这个技巧:

>>> print r"c:\test"'\\'
test\
于 2011-04-29T08:57:03.980 回答
16

另一个技巧是使用 chr(92) 计算结果为“\”。

我最近不得不清理一串反斜杠,以下是诀窍:

CleanString = DirtyString.replace(chr(92),'')

我意识到这并没有解决“为什么”,但该线程吸引了许多人寻找解决直接问题的方法。

于 2011-11-02T19:54:40.517 回答
9

由于 \" 允许在原始字符串中。那么它不能用于标识字符串文字的结尾。

为什么在遇到第一个“时不停止解析字符串文字?

如果是这种情况,那么 \" 将不允许在字符串文字中。但它是。

于 2009-03-15T16:59:09.537 回答
4

语法不正确的原因r'\'是,尽管字符串表达式是原始的,但使用的引号(单引号或双引号)总是必须转义,否则它们会标记引号的结尾。因此,如果你想在单引号字符串中表达单引号,除了使用\'. 同样适用于双引号。

但你可以使用:

'\\'
于 2009-03-15T12:59:20.520 回答
1

另一位后来删除了他们的答案的用户(不确定他们是否希望得到认可)建议 Python 语言设计者可以通过使用相同的解析规则并将转义字符扩展为原始形式作为事后的想法来简化解析器设计(如果文字被标记为原始)。

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

于 2009-03-15T14:20:01.667 回答
0

从 C 开始,我很清楚单个 \ 用作转义字符,允许您将特殊字符(例如换行符、制表符和引号)放入字符串中。

这确实不允许 \ 作为最后一个字符,因为它会转义 " 并使解析器窒息。但正如前面指出的 \ 是合法的。

于 2009-03-15T17:14:37.707 回答
0

一些技巧 :

1)如果您需要为路径操作反斜杠,那么标准 python 模块 os.path 是您的朋友。例如 :

os.path.normpath('c:/folder1/')

2)如果您想在其中构建带有反斜杠的字符串,但在字符串的末尾没有反斜杠,那么原始字符串是您的朋友(在您的文字字符串之前使用'r'前缀)。例如 :

r'\one \two \three'

3)如果您需要在变量 X 中使用反斜杠作为字符串前缀,那么您可以这样做:

X='dummy'
bs=r'\ ' # don't forget the space after backslash or you will get EOL error
X2=bs[0]+X  # X2 now contains \dummy

4)如果您需要在末尾创建一个带有反斜杠的字符串,则将提示 2 和 3 结合起来:

voice_name='upper'
lilypond_display=r'\DisplayLilyMusic \ ' # don't forget the space at the end
lilypond_statement=lilypond_display[:-1]+voice_name

现在 lilypond_statement 包含"\DisplayLilyMusic \upper"

蟒蛇万岁!:)

n3on

于 2009-03-15T22:22:05.283 回答
0

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

于 2017-12-30T06:14:03.563 回答
-1

我遇到了这个问题,并找到了一个对某些情况有好处的部分解决方案。尽管 python 不能以单个反斜杠结束字符串,但可以将其序列化并保存在末尾带有单个反斜杠的文本文件中。因此,如果您需要在计算机上保存带有单个反斜杠的文本,则可以:

x = 'a string\\' 
x
'a string\\' 

# Now save it in a text file and it will appear with a single backslash:

with open("my_file.txt", 'w') as h:
    h.write(x)

顺便说一句,如果您使用 python 的 json 库转储它,它不适用于 json。

最后,我使用 Spyder,我注意到如果我通过在变量资源管理器中双击变量名称在蜘蛛的文本编辑器中打开变量,它会显示一个反斜杠,并且可以通过这种方式复制到剪贴板(不是对大多数需求非常有帮助,但可能对某些需求有帮助..)。

于 2018-10-10T11:23:43.437 回答