从技术上讲,任何奇数个反斜杠,如 the documentation 中所述。
>>> 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
似乎解析器可以将原始字符串中的反斜杠视为常规字符(这不是原始字符串的全部内容吗?),但我可能遗漏了一些明显的东西。
关于 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, \, ' 但现在没有终止引号。
最后一个案例表明,根据文档,现在解析器找不到结束引号,因为您在上面看到的最后一个引号是字符串的一部分,即反斜杠不能在此处最后,因为它会“吞噬”字符串结束字符。
原因在我以粗体突出显示的那部分的部分中进行了解释:
字符串引号可以用反斜杠转义,但反斜杠保留在字符串中;例如,r"\"" 是由两个字符组成的有效字符串文字:反斜杠和双引号;r"\" 不是有效的字符串文字(即使原始字符串也不能以奇数个反斜杠结尾)。具体来说,原始字符串不能以单个反斜杠结尾(因为反斜杠会转义后面的引号字符)。另请注意,单个反斜杠后跟换行符被解释为这两个字符作为字符串的一部分,而不是作为续行.
所以原始字符串不是 100% 原始的,还有一些基本的反斜杠处理。
r"foo\bar\baz" "\\"
(如果有歧义,用括号括起来)将在编译时创建一个文字,其中的第一部分是原始的,只有最后一点是非原始的,以允许尾部反斜杠。
它就是这样儿的!我认为它是 python 中的小缺陷之一!
我认为没有充分的理由,但绝对不是解析;用 \ 作为最后一个字符来解析原始字符串真的很容易。
问题是,如果您允许 \ 成为原始字符串中的最后一个字符,那么您将无法将 " 放入原始字符串中。似乎 python 使用了 allow " 而不是允许 \ 作为最后一个字符。
但是,这不应该造成任何麻烦。
如果您担心无法轻松编写诸如 c:\mypath\
之类的 windows 文件夹路径,请不要担心,因为您可以将它们表示为 r"C:\mypath"
,并且,如果您需要附加子目录名称,请不要这样做它与字符串连接,因为无论如何这不是正确的方法!使用 os.path.join
>>> import os
>>> os.path.join(r"C:\mypath", "subfolder")
'C:\\mypath\\subfolder'
为了让你用斜杠结束原始字符串,我建议你可以使用这个技巧:
>>> print r"c:\test"'\\'
test\
另一个技巧是使用 chr(92) 计算结果为“\”。
我最近不得不清理一串反斜杠,以下是诀窍:
CleanString = DirtyString.replace(chr(92),'')
我意识到这并没有解决“为什么”,但该线程吸引了许多人寻找解决直接问题的方法。
"\\"
(带反斜杠的非原始字符串)
由于 \" 允许在原始字符串中。那么它不能用于标识字符串文字的结尾。
为什么在遇到第一个“时不停止解析字符串文字?
如果是这种情况,那么 \" 将不允许在字符串文字中。但它是。
\"
,或在双引号原始字符串末尾的 \。使用统计信息必须有利于任何地方的两个字符序列而不是最后的一个字符序列。
r'\'
语法不正确的原因是,尽管字符串表达式是原始的,但使用的引号(单引号或双引号)总是必须转义,否则它们会标记引号的结尾。所以如果你想在单引号字符串中表达单引号,除了使用\'
之外别无他法。同样适用于双引号。
但你可以使用:
'\\'
另一位后来删除了他们的答案的用户(不确定他们是否希望得到认可)建议 Python 语言设计者可以通过使用相同的解析规则并将转义字符扩展为原始形式作为事后的想法来简化解析器设计(如果文字被标记为原始)。
我认为这是一个有趣的想法,并将其作为社区 wiki 供后代使用。
从 C 开始,我很清楚单个 \ 用作转义字符,允许您将特殊字符(例如换行符、制表符和引号)放入字符串中。
这确实不允许 \ 作为最后一个字符,因为它会转义 " 并使解析器窒息。但正如前面指出的 \ 是合法的。
一些技巧 :
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
os.path.normpath
将删除尾部反斜杠...那么我应该如何将文件名连接到路径中...
尽管有其作用,但即使是原始字符串也不能以单个反斜杠结尾,因为反斜杠转义了后面的引号字符 - 您仍然必须转义周围的引号字符才能将其嵌入字符串中。也就是说,r"...\" 不是一个有效的字符串字面量——原始字符串不能以奇数个反斜杠结尾。如果您需要以单个反斜杠结束原始字符串,则可以使用两个并切掉第二个。
我遇到了这个问题,并找到了一个对某些情况有好处的部分解决方案。尽管 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,我注意到如果我通过在变量资源管理器中双击变量名称在蜘蛛的文本编辑器中打开变量,它会显示一个反斜杠,并且可以通过这种方式复制到剪贴板(不是对大多数需求非常有帮助,但可能对某些需求有帮助..)。
x = r"I have ""an apple"""
代表I have "an apple"
. 一个问题是 python 允许a="a""b"
或a="a" "b"
导致a="ab"
。所以要使用双引号,python 需要禁止a="a""b"
的用例。