提问人:Bite code 提问时间:1/18/2010 最后编辑:martineauBite code 更新时间:11/14/2023 访问量:661363
“u”和“r”字符串前缀到底有什么作用,什么是原始字符串文字?
What exactly do "u" and "r" string prefixes do, and what are raw string literals?
问:
在问这个问题时,我意识到我对原始字符串知之甚少。对于自称是 Django 培训师的人来说,这很糟糕。
我知道什么是编码,我知道只有编码才能做什么,因为我明白了什么是Unicode。u''
但究竟做了什么?它会产生什么样的字符串?
r''
最重要的是,到底做了什么?
ur''
最后,有没有可靠的方法可以从Unicode字符串恢复到简单的原始字符串?
啊,顺便说一句,如果你的系统和你的文本编辑器字符集设置为UTF-8,实际上有什么作用吗?
u''
答:
“u”前缀表示值具有类型而不是 。unicode
str
带有“r”前缀的原始字符串文本可以转义其中的任何转义序列,2 也是如此。因为它们转义了转义序列,所以你不能用一个反斜杠结束字符串文本:这不是一个有效的转义序列(例如)。len(r"\n")
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(或 UTF-8)仅当注释或文档字符串需要提及需要 Latin-1 的作者姓名时才应使用;否则,使用 \x、\u 或 \U 转义是在字符串文本中包含非 ASCII 数据的首选方法。
Python 2 中有两种类型的字符串:传统类型和较新类型。如果键入的字符串文本不带 in front,则会得到存储 8 位字符的旧类型,而 in front 则会得到可以存储任何 Unicode 字符的较新类型。str
unicode
u
str
u
unicode
它根本不会改变类型,它只是改变了字符串文字的解释方式。如果没有 ,反斜杠将被视为转义字符。使用 时,反斜杠被视为文字。无论哪种方式,类型都是相同的。r
r
r
ur
当然是一个 Unicode 字符串,其中反斜杠是文字反斜杠,而不是转义码的一部分。
您可以尝试使用该函数将 Unicode 字符串转换为旧字符串,但如果有任何 Unicode 字符无法在旧字符串中表示,则会出现异常。如果您愿意,您可以先用问号替换它们,但这当然会导致这些字符不可读。如果要正确处理 unicode 字符,则不建议使用该类型。str()
str
评论
r"\"
实际上没有任何“原始字符串”;有原始字符串文本,它们正是在开始引号之前用 an 标记的字符串文本。'r'
“原始字符串文字”是字符串文字的语法略有不同,其中反斜杠 , 被理解为“只是一个反斜杠”(除非它正好在引号之前,否则会终止文本) -- 没有“转义序列”来表示换行符、制表符、退格键、表单馈送等。在普通的字符串文本中,每个反斜杠必须加倍,以避免被视为转义序列的开始。\
这种语法变体之所以存在,主要是因为正则表达式模式的语法中有很多反斜杠(但从来不会在末尾,所以上面的“except”子句无关紧要),当你避免将每个语法加倍时,它看起来会更好一些——仅此而已。它也获得了一些流行来表达本机 Windows 文件路径(使用反斜杠而不是像其他平台那样的常规斜杠),但这很少需要(因为普通斜杠在 Windows 上也大多工作正常)并且不完美(由于上面的“除外”子句)。
r'...'
是一个字节字符串(在 Python 2.* 中),是一个 Unicode 字符串(同样,在 Python 2.* 中),其他三种引号中的任何一种也会产生完全相同类型的字符串(例如,、、、都是字节字符串,依此类推)。ur'...'
r'...'
r'''...'''
r"..."
r"""..."""
不知道你说的“返回”是什么意思 - 没有本质上的后退和前进方向,因为没有原始字符串类型,它只是一种替代语法来表达完全正常的字符串对象,字节或 unicode。
是的,在 Python 2.* 中,当然总是不同于 just -- 前者是 unicode 字符串,后者是字节字符串。对文本的编码可能表示是一个完全正交的问题。u'...'
'...'
例如,考虑(Python 2.6):
>>> sys.getsizeof('ciao')
28
>>> sys.getsizeof(u'ciao')
34
当然,Unicode 对象会占用更多的内存空间(显然,对于非常短的字符串来说,差异非常小;-)。
评论
u
r
ur'str'
ru'str'
r
\
SyntaxError: EOL while scanning string literal
\\
\
sys.getsizeof('cioa') == sys.getsizeof(r'cioa') == sys.getsizeof(u'cioa')
type('cioa') == type(r'cioa') == type(u'cioa')
sys.getsizeof('\ncioa') == sys.getsizeof(u'\ncioa') != sys.getsizeof(r'\ncioa')
“原始字符串”表示它按显示方式存储。例如,只是一个反斜杠,而不是转义。'\'
评论
让我简单地解释一下: 在 python 2 中,您可以将字符串存储为 2 种不同的类型。
第一个是 ASCII,它是 python 中的 str 类型,它使用 1 字节的内存。(256个字符,主要存储英文字母和简单符号)
第二种类型是 UNICODE,它是 python 中的 unicode 类型。Unicode 存储所有类型的语言。
默认情况下,python 更喜欢 str 类型,但如果你想以 unicode 类型存储字符串,你可以把 u 放在文本前面,比如 u'text',或者你可以通过调用 unicode('text') 来做到这一点
因此,u 只是调用函数将 str 转换为 unicode 的捷径。就是这样!
现在 r 部分,你把它放在文本前面,告诉计算机文本是原始文本,反斜杠不应该是转义字符。r'\n' 不会创建新的行字符。它只是包含 2 个字符的纯文本。
如果要将 str 转换为 unicode 并将原始文本放入其中,请使用 因为 ru 会引发错误。
现在,重要的部分:
你不能使用 r 存储一个反斜杠,这是唯一的例外。 所以这个代码会产生错误:r'\'
要存储一个反斜杠(只有一个),您需要使用'\\'
如果要存储 1 个以上的字符,您仍然可以使用 r,例如 r'\\' 将产生 2 个反斜杠,如您预期的那样。
我不知道 r 不适用于一个反斜杠存储的原因,但还没有人描述原因。我希望这是一个错误。
评论
r'\'
'\'
r'xxxxxx\'
str
r'\'
给出了一个预期,并在以下部分注明: docs.python.org/3/reference/...: @Jeyekomon的另一个回答中也指出了这一点。SyntaxError: unterminated string literal
Even in a raw literal, quotes can be escaped with a backslash, but the backslash remains in the result...
也许这是显而易见的,也许不是,但你可以通过调用 x=chr(92) 来制作字符串 '\'
蟒蛇2
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
蟒蛇3 (3.11.1)
x=chr(92)
print(type(x), len(x)) # <class 'str'> 1
# Note The Type Change To Class
y='\\'
print(type(y), len(y)) # <class 'str'> 1
# Note The Type Change To Class
x==y # True
x is y # True
# Note this is now True
评论
x is y
在 python3 中计算结果为 True?
x is y
True
x == y
Unicode 字符串文本
Python 3 中不再使用 Unicode 字符串文字(字符串文字前缀为 )。它们仍然有效,但只是为了与 Python 2 兼容。u
原始字符串文本
如果要创建仅由易于键入的字符(如英文字母或数字)组成的字符串文本,则只需键入它们即可:.但是,如果您还想包含一些更奇特的角色,则必须使用一些解决方法。'hello world'
解决方法之一是转义序列。例如,通过这种方式,只需在字符串文本中添加两个易于键入的字符,即可在字符串中表示新行。因此,当您打印字符串时,单词将打印在单独的行上。这非常方便!\n
'hello\nworld'
另一方面,有时您可能希望将实际字符包含在字符串中 - 您可能不希望它们被解释为换行符。请看这些例子:\
n
'New updates are ready in c:\windows\updates\new'
'In this lesson we will learn what the \n escape sequence does.'
在这种情况下,您可以像这样在字符串文字前面加上字符:Python 不会解释任何转义序列。字符串将完全按照您创建的方式打印。r
r'hello\nworld'
原始字符串文字不完全是“原始”的吗?
许多人希望原始字符串文字是原始的,因为“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\'
评论