IMXYLZ

Str - 字符串

关于编码

Python 3.0开始,字符串(str)已经完全是unicode编码。这与Python 2.x完全不一样。

Python 3.x采用类似Java里面的字符串处理模式(我个人认为Java在字符编码这方面是做得最好的)。 str表示unicode文本,bytes表示字节。而且str和unicode不可以混着使用(在python 2.x里面8-bits字符是可以和 7-bit的bytes混着使用的)。

str类似Java里面的String类,bytes类似Java里面的byte[]。 Java里面的String和byte[]的转换是:

`byte[]` <== java.lang.String.getBytes(String charset)
`byte[]` ==> java.lang.String.String(byte[] bytes, String charset)

而在Python 3.x里面str和bytes的转换是:

`bytes` <== str.encode(encoding)
`str` <== bytes.decode(encoding)

或者另外一种方式:

`bytes` <== bytes(str,encoding)
`str` <== str(bytes,encoding)

str和bytes都是不可修改的对象。bytearray对象是可修改的对象。

Tips: * str是unicode编码(内存中基础编码应该是UTF-16/或UTF-32,待补充) * 任何时候str和bytes之间转换都需要强制指定编码,不要依赖于操作系统的默认编码 * str和bytes都是不可修改的对象 * 一种近似的理解是python 3.x中的str和python 2.x中的unicode类似,python 3.x中的bytes和python 2.x中的str类似,但语义不完全一样

基础使用

直接的字符串定义有四种形式:

s='中文'
s="中国"
s="""历史"""
s='''历史'''

通常而已,单双引号的合理使用在转义时非常方便。而在其他语言中要转义双引号还是很麻烦的,例如java中的json字符串书写就非常痛苦。 而在python中,这是非常容易的事情:

s="""{"name":"adyliu","nick":"imxylz","blog":"http://imxylz.com"}"""

另外在console中print()函数会自动输出合适的单引号或者双引号。 也可以使用原始字符串而不需要转义,例如:

s=r'C:\Windows\System32\drivers\etc\hosts'

python 中字符串可以直接使用比较运算,例如:

>>> s1,s2='ok','o'+'k'
>>> s1==s2
True    
>>> 'o'<'k'
False

分片

分片操作有三种语法(start/end/step都必须是整数): * seq[start] * seq[start:end] * seq[start:end:step]

事实上支持分片的类型是Sequence Type,包括list,tuple,range类型,例如str、bytes就是range类型。 对于字符串s=“Light ray”,各个字符的索引位置如下:

str slice

忽略起始值start表示0,忽略结束值end表示结尾。例如:

>>> s="Light ray"
>>> s[0:5]
'Light'
>>> s[1:6]
'ight '
>>> s[:]
'Light ray'
>>> s[:-4]
'Light'
>>> s[6:]
'ray'
>>> s[-3:]
'ray'
>>> s[::2]
'Lgtry'
>>> s[::-2]
'yrtgL'
>>> s[::-1]
'yar thgiL'

在这个例子中,反转字符串可以用: s[::-1]

基本操作

字符串的基本操作有:

  • x in s ==> 判断字符串s是否包含x,返回True/False
  • x not in s
  • s + t ==> 拼接字符串,组成新的字符串
  • sn或者ns ==> n个字符串s拼接在一起
  • len(s) ==> 字符串长度(unicode字符数目,不是字节长度)
  • min(s) ==> 字符串中最小的字符(unicode值)
  • max(s) ==> 字符串中最大的字符
  • s.count(x) ==> 字符串s中x出现的次数

完整API列表

完整的字符串API列表:

  • str.capitalize() ==> 首字母大写
  • str.center(width,char) ==> 字符串前后填充,默认用空格填充,填充后长度是width,如果s本身已经超过width,则不填充。
  • str.endswith(x,start,end) ==> 检测字符串是否以x结尾
  • str.startswith(prefix[,start[,end]]) ==> 检测字符串使用以prefix开始
  • str.expandtabs([tabsize]) ==> 将字符串中的tab使用8个(或者指定个数)的空格替换
  • str.find(sub[,start[,end]]) ==> 查找子串的索引位置,找不到会返回-1,类似Java中的indexOf
  • str.rfind(sub[,start[,end]]) ==> 从右侧开始查找子串的索引位置
  • str.index(sub[,start[,end]]) ==> 查找字串的索引位置,和find类似,只是找不到会抛出ValueError异常
  • str.rindex(sub[,start[,end]]) ==> 从右侧开始查找字串的索引位置
  • str.isalnum() ==> 如果s非空,并且每个字符都是字母或者数字,返回True
  • str.isalpha() ==> 如果s非空,并且每个字符都是字母
  • str.isdecimal() ==> 如果s非空,并且每个字符都是10进制的数字[1]
  • str.isdigit() ==> 如果s非空,并且每个字符都是数字[1]
  • str.isnumeric() ==> 如果s非空,并且每个字符都是数字[1]
  • str.isidentifier() ==> 如果s非空,并且是一个有效的标识符
  • str.islower() ==> 如果s非空,有一个小写字符,并且所有可小些的字符都是小写的
  • str.lower() ==> 字符串转换为小写
  • str.isprintable() ==> 如果s非空,并且每个子否都是可打印的,包括空格,但是不包括换行
  • str.isspace() ==> 如果s非空,并且每一个字符都是空白字符
  • str.istitle() ==> 如果s非空,并且首字母大写
  • str.title() ==> 字符串每个单词首字母大写
  • str.isupper() ==> 如果s非空,有一个大写字符,并且所有可大写的字符都是大写的
  • str.upper() ==> 字符串转换为大写
  • str.join(iterable) ==> 将字符串序列以指定字符串连接起来
  • str.ljust(width[,fillchar]) ==> 使用空格或者指定字符(char)来填充的左对齐字符串,类似str.center()
  • str.rjust(width[,fillchar]) ==> 使用空格或者指定字符(char)来填充的右对齐字符串,类似str.center()
  • str.partition(sep) ==> 返回3个字符串的元组,包括sep的左边部分、sep、sep右边的部分。如果sep不存在,则返回s与两个空字符串。
  • str.rpartition(sep) ==> 类似partition(sep),唯一的区别是,如果sep不存在,那么返回两个空字符串和s,这是s是第三个元素。
  • str.replace(old,new[,count]) ==> 字符串替换,纯文本替换(非正则表达式),最多替换count次数如果有的话
  • str.strip([chars]) ==> 将头尾的空白字符(或者指定字符)去掉,类似Java中的trim()
  • str.rstrip([chars]) ==> 将尾部的空白字符(或者指定字符)去掉
  • str.lstrip([chars]) ==> 将头部的空白字符(或者指定字符)去掉

  • str.split(sep=None,maxsplit=-1) ==> 分隔字符串为字符串列表(默认使用空白符为分隔符)

  • str.rsplit(sep=None,maxsplit=-1) ==> 从右侧开始分隔字符串为字符串列表
  • str.splitlines([keepends]) ==> 使用换行符分隔字符串为字符串列表
  • str.swapcase() ==> 字符串中的大小写交换
  • str.zfill(width) ==> 如果字符串长度不够,那么在开头填充’0’字符以便达到指定长度

str.encode/bytes.decode

再次讨论编码的问题。

str.encode(encoding=‘utf-8’,errors=‘strict’)

将字符串转换为字节时,可选两个参数,encoding和errors。默认情况下encoding是utf-8。 对于errors,默认是’strict’,这表示如果遇到一个不可编码的字节,那么就会抛出UnicodeError异常。 最常用的errors值为:

  • strict: 抛出异常如果编码错误
  • replace: 替换不可编码的字节为’?’
  • ignore: 忽略不可编码的字节

同样,对于bytes.decode()和bytearray.decode()也有这两个参数。意义与str类似。

补充

Unicode内存描述

Python 3.x 在内存中,Unicode通常以UCS-2格式,也就是UTF-16格式来表示前65535个字符。也有USC-4也就是UTF-32来描述字符的。

如果以UTF-32来描述字符,那么就有1114111个字符。我们可以通过sys.maxunicode来检测:

>>> import sys
>>> sys.maxunicode
1114111

如果输出1114111那么就是USC-4格式,如果输出65535那么就是USC-2格式。


Python 3.x 标准库笔记

Comments

回顶部