在问这个问题时,我意识到我对原始字符串不太了解。对于自称是Django教练的人来说,这太糟糕了。

我知道什么是编码,我知道只有“u”才能做什么,因为我得到了什么是Unicode。

但“r”到底做什么?它会产生什么样的字符串?最重要的是,你到底在干什么?最后,有没有可靠的方法可以从Unicode字符串返回到简单的原始字符串?哦,顺便问一下,如果您的系统和文本编辑器字符集设置为UTF-8,那么您实际上做了什么吗?


当前回答

“原始字符串”意味着它按显示方式存储。例如,“\”只是反斜杠而不是转义。

其他回答

“原始字符串”意味着它按显示方式存储。例如,“\”只是反斜杠而不是转义。

“u”前缀表示值的类型为unicode而不是str。

带“r”前缀的原始字符串文本对其中的任何转义序列进行转义,因此len(r“\n”)为2。因为它们是转义序列,所以不能用一个反斜杠结束字符串文字:这不是有效的转义序列(例如r“\”)。

“Raw”不是类型的一部分,它只是表示值的一种方式。例如,“\\n”和r“\n”是相同的值,就像32、0x20和0b100000是相同的。

可以使用unicode原始字符串文字:

>>> u = ur"\n"
>>> print type(u), len(u)
<type 'unicode'> 2

源文件编码只决定如何解释源文件,否则不会影响表达式或类型。但是,建议避免使用非ASCII编码会改变含义的代码:

使用ASCII(或UTF-8,对于Python 3.0)的文件不应有编码cookie。只有当注释或文档字符串需要提及需要拉丁-1的作者名称时,才应使用拉丁-1(或UTF-8);否则,使用\x、\u或\u转义是在字符串文本中包含非ASCII数据的首选方式。

也许这是显而易见的,也许不是,但是您可以通过调用x=chr(92)来创建字符串“\”

x=chr(92)
print type(x), len(x) # <type 'str'> 1
y='\\'
print type(y), len(y) # <type 'str'> 1
x==y   # True
x is y # False

Python 2中有两种字符串类型:传统的str类型和较新的unicode类型。如果键入一个字符串文本,前面没有u,则会得到存储8位字符的旧str类型,而前面有u,则得到可以存储任何unicode字符的新unicode类型。

r根本不改变类型,它只是改变字符串文本的解释方式。如果没有r,反斜杠将被视为转义字符。使用r时,反斜杠被视为文字。无论哪种方式,类型都是相同的。

ur当然是Unicode字符串,其中反斜杠是字面反斜杠,而不是转义码的一部分。

您可以尝试使用str()函数将Unicode字符串转换为旧字符串,但如果有任何Unicode字符无法在旧字符串中表示,则会出现异常。如果你愿意,你可以先用问号代替它们,但这当然会导致这些字符无法阅读。如果要正确处理unicode字符,建议不要使用str类型。

实际上没有任何“原始字符串”;有一些原始字符串文字,它们正好是在开头引号前用“r”标记的字符串文字。

“原始字符串文字”是字符串文字的一种稍有不同的语法,其中反斜杠\被视为“仅反斜杠”的意思(除非它正好在引号之前,否则会终止文字)——没有“转义序列”来表示换行符、制表符、退格符、表单提要等。在正常字符串文字中,每个反斜杠必须加倍,以避免作为转义序列的开始。

这种语法变体之所以存在,主要是因为正则表达式模式的语法中有大量的反斜杠(但永远不会在末尾,所以上面的“except”子句无关紧要),并且当您避免将它们中的每一个都加倍时,它看起来会更好一些——仅此而已。它还流行于表示本机Windows文件路径(使用反斜杠代替其他平台上的正斜杠),但这很少需要(因为通常的斜杠在Windows上也很好),而且不完美(由于上面的“except”子句)。

r'…'是字节字符串(在Python 2.*中),ur'…'是一个Unicode字符串(在Python 2.*中也是如此),其他三种引号中的任何一种都会产生完全相同类型的字符串(例如,r'…'、r'…''…''、r“…”、r“”…“”都是字节字符串,依此类推)。

不知道你所说的“后退”是什么意思——没有本质上的后退和前进方向,因为没有原始字符串类型,它只是一种替代语法,可以表达完全正常的字符串对象,字节或unicode。

是的,在Python 2.*中,u'…'当然总是不同于“…”——前者是unicode字符串,后者是字节字符串。文字的编码方式是一个完全正交的问题。

例如,考虑(Python 2.6):

>>> sys.getsizeof('ciao')
28
>>> sys.getsizeof(u'ciao')
34

当然,Unicode对象占用了更多的内存空间(很明显,对于非常短的字符串,差异很小;-)。