“u”和“r”字符串标志到底有什么作用,什么是原始字符串文字?
-
21-09-2019 - |
题
一边询问 这个问题, ,我意识到我对原始字符串了解不多。对于自称是 Django 培训师的人来说,这很糟糕。
我知道什么是编码,我也知道什么 u''
自从我了解了什么是 Unicode 以来,就只有这个了。
但有什么作用
r''
究竟做什么?它会产生什么样的字符串?最重要的是,到底是做什么的
ur''
做?最后,有没有可靠的方法可以从 Unicode 字符串返回到简单的原始字符串?
啊,顺便说一句,如果您的系统和文本编辑器字符集设置为 UTF-8,
u''
实际上做了什么吗?
解决方案
其实并没有什么“原始的” 细绳”;有生的 字符串文字, ,它们正是由 标记的字符串文字 'r'
在开盘报价之前。
“原始字符串文字”与字符串文字的语法略有不同,其中反斜杠, \
, 被视为“只是一个反斜杠”(除非它出现在引号之前,否则会终止文字)——没有“转义序列”来表示换行符、制表符、退格键、换页符等。在普通字符串文字中,每个反斜杠必须加倍以避免被视为转义序列的开头。
这种语法变体的存在主要是因为正则表达式模式的语法中含有大量反斜杠(但永远不会出现在末尾,因此上面的“except”子句并不重要),并且当您避免将它们中的每一个都加倍时,它看起来会更好一些 - - 就这样。它在表达本机 Windows 文件路径(使用反斜杠而不是像其他平台上的常规斜杠)方面也受到了一些欢迎,但很少需要(因为普通斜杠大多数在 Windows 上也能正常工作)并且不完善(由于“例外”子句)多于)。
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 对象当然需要更多的内存空间(对于很短的字符串来说,差异非常小,显然;-)。
其他提示
python中有两种类型的字符串:传统的 str
类型和较新的 unicode
类型。如果您键入不带 u
在你前面你得到旧的 str
类型存储8位字符,并与 u
在前面你会得到更新的 unicode
可以存储任何 Unicode 字符的类型。
这 r
根本不改变类型,它只是改变字符串文字的解释方式。如果没有 r
, 、反斜杠被视为转义字符。随着 r
, ,反斜杠被视为文字。无论哪种方式,类型都是相同的。
ur
当然是一个 Unicode 字符串,其中反斜杠是文字反斜杠,而不是转义码的一部分。
您可以尝试使用以下命令将 Unicode 字符串转换为旧字符串 str()
函数,但如果有任何 unicode 字符无法在旧字符串中表示,则会出现异常。如果您愿意,可以先用问号替换它们,但这当然会导致这些字符不可读。不建议使用 str
如果您想正确处理 unicode 字符,请键入。
'原始字符串' 意味着它按其出现的样子存储。例如, '\'
只是一个 反斜杠 而不是 逃跑.
“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。仅当注释或文档字符串需要提及需要 Latin-1 的作者姓名时才应使用 Latin-1(或 UTF-8);否则,使用 \x、\u 或 \U 转义符是在字符串文字中包含非 ASCII 数据的首选方法。
我简单解释一下:在 python 2 中,您可以以两种不同的类型存储字符串。
第一个是 ASCII码 这是 斯特 在Python中输入,它使用1字节内存。(256个字符,主要存储英文字母和简单符号)
第二种是 统一码 这是 统一码 在python中输入,它使用2字节内存。(65536 个字符,因此这包括地球上所有语言的所有字符)
默认情况下,python会更喜欢 斯特 输入,但如果你想存储字符串 统一码 你可以输入的类型 你 在文字前面,例如 你'发短信' 或者您可以通过致电来做到这一点 统一码('文本')
所以 你 只是调用函数进行强制转换的一种简短方法 斯特 到 统一码. 。就是这样!
现在 r 部分,你把它放在文本前面,告诉计算机该文本是原始文本,反斜杠不应该是转义字符。 r' ' 不会创建新的行字符。它只是包含 2 个字符的纯文本。
如果你想转换 斯特 到 统一码 并将原始文本放在那里,使用 你的 因为 汝 会引发错误。
现在,重要的部分:
您不能使用以下方式存储一个反斜杠 r, ,这是唯一的例外。所以这段代码会产生错误: r'\'
要存储反斜杠(只有一个),您需要使用 '\\'
如果你想存储超过 1 个字符,你仍然可以使用 r 喜欢 r'\\' 将如您所料产生 2 个反斜杠。
我不知道为什么 r 不适用于一个反斜杠存储,但尚未有人描述其原因。我希望这是一个错误。
也许这是显而易见的,也许不是,但你可以让字符串 '\' 通过致电 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
Unicode 字符串文字
Unicode 字符串文字(前缀为的字符串文字 u
) 是 不再使用 在Python 3中。它们仍然有效,但是 只是为了兼容性目的 与Python 2.
原始字符串文字
如果您想创建一个仅包含易于输入的字符(例如英文字母或数字)的字符串文字,您只需输入它们即可: 'hello world'
. 。但如果您还想包含一些更奇特的角色,则必须使用一些解决方法。解决方法之一是 转义序列. 。例如,您可以通过添加两个易于输入的字符来表示字符串中的新行 \n
到你的字符串文字。所以当你打印 'hello\nworld'
字符串,单词将打印在单独的行上。这非常方便!
另一方面,在某些情况下,您想要创建包含转义序列的字符串文字,但不希望 Python 解释它们。你希望他们成为 生的. 。看看这些例子:
'New updates are ready in c:\windows\updates\new'
'In this lesson we will learn what the \n escape sequence does.'
在这种情况下,您只需在字符串文字前面加上前缀 r
像这样的字符: r'hello\nworld'
Python 不会解释任何转义序列。该字符串将完全按照您创建的方式打印。
原始字符串文字不完全是“原始”吗?
许多人期望原始字符串文字在某种意义上是原始的 “Python 会忽略引号之间的任何内容”. 。那不是真的。Python 仍然可以识别所有转义序列,只是不解释它们 - 而是让它们保持不变。代表着 原始字符串文字仍然必须是有效的字符串文字.
来自 词汇定义 字符串文字的:
string ::= "'" stringitem* "'"
stringitem ::= stringchar | escapeseq
stringchar ::= <any source character except "\" or newline or the quote>
escapeseq ::= "\" <any source character>
很明显,包含裸引号字符的字符串文字(原始或非原始): 'hello'world'
或以反斜杠结尾: 'hello world\'
无效。