为什么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
看起来解析器可能只是将原始字符串中的反斜杠视为常规字符(是不是原始字符串是关于什么?),但我可能错过了一些明显的东西。 TIA!
原因在我以粗体突出显示的部分中进行了解释:
字符串引号可以使用反斜杠进行转义,但反斜杠保留在字符串中; 例如,
r"\""
是一个有效的字符串文字,由两个字符组成:反斜杠和双引号;r"\"
不是有效的字符串文本(甚至原始字符串不能以奇数个反斜杠结尾)。具体来说,原始字符串不能以单个反斜杠结尾(因为反斜杠会转义下面的引号字符)。还要注意,一个反斜杠后跟一个换行符将被解释为字符串中的两个字符,而不是行延续。
所以原始字符串不是100%原始的,还有一些基本的反斜杠处理。
关于python原始字符串的错误概念是,大多数人认为反斜杠(原始字符串内)与其他所有字符一样是一个常规字符。 不是这样。 要理解的关键是这个Python的教程序列:
当存在“ r ”或“ R ”前缀时,字符串中包含反斜杠后的字符不变,并且所有反斜杠都保留在字符串中
所以任何反斜杠后的字符都是原始字符串的一部分。 一旦解析器输入一个原始的字符串(非unicode之一)并遇到一个反斜杠它知道有2个字符(一个反斜杠和一个后面的字符)。
这条路:
r'abc \ d'包含a,b,c,\,d
包括a,b,c,\,',d
包括a,b,c, l ,
和:
r'abc \'包含a,b,c,\',但现在没有终止引号。
最后一种情况显示,根据文档现在解析器无法找到结尾引号,因为上面看到的最后一个qoute是字符串ie的一部分。 反斜杠不能在这里,因为它会'吞噬'字符串关闭字符。
它就是这样儿的! 我把它看作是python中的一个小缺陷!
我认为这不是一个好的理由,但绝对不是解析; 使用\作为最后一个字符解析原始字符串非常容易。
如果你允许\是原始字符串中的最后一个字符,那么你将不能把“在一个原始字符串内,似乎Python允许”,而不是允许\作为最后一个字符。
但是,这不应该引起任何麻烦。
如果您担心无法轻松编写Windows文件夹路径(如c:\mypath\
那么请不要担心,因为您可以将它们表示为r"C:\mypath"
,并且如果您需要追加一个子目录名字,不要用字符串连接来完成,因为它不是正确的方法! 使用os.path.join
>>> import os >>> os.path.join(r"C:\mypath", "subfolder") 'C:\\mypath\\subfolder'
另一个技巧是使用chr(92),因为它评估为“\”。
我最近不得不清理一串反斜杠,下面这个诀窍:
CleanString = DirtyString.replace(chr(92),'')
我意识到这并不关心“为什么”,但这个线程吸引了很多人寻找解决眼前的问题。
为了让你用斜杠结束一个原始字符串,我建议你可以使用这个技巧:
>>> print r"c:\test"'\\' test\
由于“\”在原始字符串中是允许的,所以不能用来标识字符串的结尾。
为什么不停止解析字符串文字,当你遇到第一个“?
如果是这样的话,那么“在字符串文字中是不会被允许的,但它是。
为什么r'\'
是语法错误的原因是虽然字符串表达式是原始的,但是使用的引号(单或双)总是必须是转义的,因为它们会标记报价的结尾。 所以,如果你想在单引号字符串中表示单引号,除了使用\'
之外没有别的办法。 同样适用于双引号。
但是你可以使用:
'\\'
另一个已经删除了他们的答案的用户(不知道他们是否想要被记入)建议Python语言设计者可以通过使用相同的解析规则并且将逃逸字符扩展为原始形式来简化解析器设计(如果文字被标记为原始的)。
我认为这是一个有趣的想法,并将其作为后代的社区维基。
从C中可以明显看出,单个\作为转义字符,可以将特殊字符(如换行符,制表符和引号)转换为字符串。
这确实不允许\作为最后一个字符,因为它会逃避“并使解析器窒息,但正如前面指出的\是合法的。
一些技巧 :
1)如果你需要操纵反斜杠的路径,那么标准的Python模块os.path是你的朋友。 例如 :
os.path.normpath( 'C:/ folder1中/')
2)如果你想在其中创建带反斜杠的字符串,但是在你的字符串的END处没有反斜线,那么原始字符串是你的朋友(在你的字符串之前使用'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