为什么python的原始字符串文字可以以一个反斜杠结尾?

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

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

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

109523 次浏览

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

但是你可以用:

'\\'

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

字符串引号可以使用 反斜杠,但反斜杠仍然存在 在字符串中;例如,r"\""是一个 由两个组成的有效字符串文字 字符:反斜杠和双字符 报价;r"\"不是一个有效的字符串 文字(即使是原始字符串也不能结束 以奇数个反斜杠)。 具体来说,原始字符串不能结束 在一个反斜杠中(因为 反斜杠将转义下面的内容 引用字符)。还要注意的是 单反斜杠后跟换行符 被解释为那两个字符 作为字符串的一部分,而不是作为一行 延续。< / p >

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

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

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

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

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

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

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

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

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

因为\"被允许在原始字符串中。那么它就不能用来标识字符串字面量的结束。

当遇到第一个“”时,为什么不停止解析字符串字面值呢?

如果是这种情况,那么\"将不被允许在字符串字面量中。但事实确实如此。

来自C,对我来说很清楚,一个\作为转义字符,允许你把特殊字符,如换行符,制表符和引号放入字符串。

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

一些建议:

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

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

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

>>> print r"c:\test"'\\'
test\

它使用Python中字符串字面值的隐式连接,并将一个用双引号分隔的字符串与另一个用单引号分隔的字符串连接起来。丑,但有用。

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

我最近不得不清理一串反斜杠,下面的技巧做到了:

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

我意识到这并没有考虑到“为什么”,但这条线索吸引了许多人寻找一个即时问题的解决方案。

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

当存在'r'或'R'前缀时,a . abc0后面的字符 反斜杠包含在字符串中而不更改,并且所有 反斜杠留在字符串

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

这种方式:

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"…“不是一个有效的字符串 字面-原始字符串不能以奇数个反斜杠结尾 如果需要用一个反斜杠结束原始字符串,可以使用 两个,切掉第二个

我遇到过这个问题,并找到了一个部分解决方案,这在某些情况下是很好的。尽管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,我注意到,如果我在蜘蛛的文本编辑器中双击变量资源管理器中的名称来打开变量,它会显示一个反斜杠,并且可以以这种方式复制到剪贴板(这对大多数需求不是很有帮助,但可能对一些..)。

原始字符串

原始字符串的简单想法是

如果我在一对引号前加上r, 我可以在引号中间加任何我想加的

不幸的是,这不起作用,因为如果 如果恰好包含引号,原始字符串将在该点结束

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

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

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

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

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

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

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

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

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

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

变体2没有帮助:

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

结论

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