跳转到内容

Python/字符串

维基教科书,自由的教学读本

字符串是以字符为单位处理的不可变序列对象,Python3的字符串固定是Unicode表示。而bytes类型是以字节(取值范围 0-255)为单位处理的不可变的序列对象。所以,从字符串至bytes需要编码(encode),给出编码集(encoding)作为参数;从bytes到字符串为解码(decode)。Python中的bytes用b'xxx'的形式表示。x可以用字符表示,也可以用ASCII编码形式\xnn表示,nn从00-ff(十六进制)共256种字符。修改一个字节串中的某个字节,不能够直接修改,需要将其转化为bytearray后再进行修改。str与bytes是Python预定义的两个类。

使用单引号',或双引号"来创建字符串。

在字符串的第一个引号前加上字母"r"(或"R"),为原始字符串:其表达式内部的所有的字符都是直接按照字面的意思来使用,没有转义特殊或不能打印的字符。 三引号(单引号或者双引号)允许一个字符串跨多行,字符串中可以包含换行符、制表符以及其他特殊字符。

引号前小写的"u"表示这里创建的是一个 Unicode 字符串。使用Python的Unicode-Escape编码来表示一个字符,如\u0020表示空格符。

Python不支持字符类型。字符也是作为一个字符串。

转义字符

[编辑]

python用反斜杠(\)转义下述字符:

  • \(在行尾时) 续行符
  • \\ 反斜杠符号
  • \' 单引号
  • \" 双引号
  • \a 响铃
  • \b 退格(Backspace)
  • \e 转义
  • \000 空
  • \n 换行
  • \v 纵向制表符
  • \t 横向制表符
  • \r 回车
  • \f 换页
  • \0yy 2位八进制数字,yy代表的字符,例如:\012代表换行
  • \xyy 2位十六进制数字,yy代表的字符,例如:\x0a代表换行
  • \uyyyy 4位十六进制数字,表示Unicode字符
  • \Uyyyyyyyy 8位十六进制数字,表示Unicode字符
  • \other 其它的字符以普通格式输出

序列操作

[编辑]

字符串作为Python的六种序列数据类型之一,支持常见的序列操作:

  • + 字符串连接
  • [] 通过索引获取字符串中字符
  • [ : ] 切片。截取字符串中的一部分
  • in 成员运算符 - 如果字符串中包含给定的字符返回 True
  • not in 成员运算符 - 如果字符串中不包含给定的字符返回 True
  • % 格式字符串,内部的格式化指示符与C语言的printf所用的一样。Python2.6 开始,新增了一种格式化字符串的函数 str.format(),它增强了字符串格式化的功能。

内建方法

[编辑]

string的方法:

方法名 描述
string.capitalize() 把字符串的第一个字符大写
string.center(width) 返回一个原字符串居中,并使用空格填充至长度 width 的新字符串
string.count(str, beg=0, end=len(string)) 返回 str 在 string 里面出现的次数,如果 beg 或者 end 指定则返回指定范围内 str 出现的次数
string.decode(encoding='UTF-8', errors='strict') 以 encoding 指定的编码格式解码 string,如果出错默认报一个 ValueError 的 异 常 , 除非 errors 指 定 的 是 'ignore' 或 者'replace'
string.encode(encoding='UTF-8', errors='strict') 以 encoding 指定的编码格式编码 string,如果出错默认报一个ValueError 的异常,除非 errors 指定的是'ignore'或者'replace'
string.endswith(obj, beg=0, end=len(string)) 检查字符串是否以 obj 结束,如果beg 或者 end 指定则检查指定的范围内是否以 obj 结束,如果是,返回 True,否则返回 False.
string.expandtabs(tabsize=8) 把字符串 string 中的 tab 符号转为空格,tab 符号默认的空格数是 8。
string.find(str, beg=0, end=len(string)) 检测 str 是否包含在 string 中,如果 beg 和 end 指定范围,则检查是否包含在指定范围内,如果是返回开始的索引值,否则返回-1
string.format() 格式化字符串
string.index(str, beg=0, end=len(string)) 跟find()方法一样,只不过如果str不在 string中会报一个异常.
string.isalnum() 如果 string 至少有一个字符并且所有字符都是字母或数字则返回 True,否则返回 False
string.isalpha() 如果 string 至少有一个字符并且所有字符都是字母则返回 True,否则返回 False
string.isdecimal() 如果 string 只包含十进制数字则返回 True 否则返回 False.
string.isdigit() 如果 string 只包含数字则返回 True 否则返回 False.
string.islower() 如果 string 中包含至少一个区分大小写的字符,并且所有这些(区分大小写的)字符都是小写,则返回 True,否则返回 False
string.isnumeric() 如果 string 中只包含数字字符,则返回 True,否则返回 False
string.isspace() 如果 string 中只包含空格,则返回 True,否则返回 False.
string.istitle() 如果 string 是标题化的(见 title())则返回 True,否则返回 False
string.isupper() 如果 string 中包含至少一个区分大小写的字符,并且所有这些(区分大小写的)字符都是大写,则返回 True,否则返回 False
string.join(seq) 以 string 作为分隔符,将 seq 中所有的元素(的字符串表示)合并为一个新的字符串
string.ljust(width) 返回一个原字符串左对齐,并使用空格填充至长度 width 的新字符串
string.lower() 转换 string 中所有大写字符为小写
string.lstrip() 截掉 string 左边的空格
string.maketrans(intab, outtab]) maketrans() 方法用于创建字符映射的转换表,对于接受两个参数的最简单的调用方式,第一个参数是字符串,表示需要转换的字符,第二个参数也是字符串表示转换的目标。
max(str) 返回字符串 str 中最大的字母。
min(str) 返回字符串 str 中最小的字母。
string.partition(str) 有点像 find()和 split()的结合体,从 str 出现的第一个位置起,把 字 符 串 string 分 成 一 个 3 元 素 的 元 组 (string_pre_str,str,string_post_str),如果 string 中不包含str 则 string_pre_str == string.
string.replace(str1, str2, num=string.count(str1)) 把 string 中的 str1 替换成 str2,如果 num 指定,则替换不超过 num 次.
string.rfind(str, beg=0,end=len(string) ) 类似于 find()函数,不过是从右边开始查找.
string.rindex( str, beg=0,end=len(string)) 类似于 index(),不过是从右边开始.
string.rjust(width) 返回一个原字符串右对齐,并使用空格填充至长度 width 的新字符串
string.rpartition(str) 类似于 partition()函数,不过是从右边开始查找.
string.rstrip() 删除 string 字符串末尾的空格.
string.split(str="", num=string.count(str)) 以 str 为分隔符切片 string,如果 num有指定值,则仅分隔 num 个子字符串
string.splitlines([keepends]) 按照行('\r', '\r\n', \n')分隔,返回一个包含各行作为元素的列表,如果参数 keepends 为 False,不包含换行符,如果为 True,则保留换行符
string.startswith(obj, beg=0,end=len(string)) 检查字符串是否是以 obj 开头,是则返回 True,否则返回 False。如果beg 和 end 指定值,则在指定范围内检查
string.strip([obj]) 在 string 上执行 lstrip()和 rstrip()
string.swapcase() 翻转 string 中的大小写
string.title() 返回"标题化"的 string,就是说所有单词都是以大写开始,其余字母均为小写(见 istitle())
string.translate(str, del="") 根据 str 给出的表(包含 256 个字符)转换 string 的字符,要过滤掉的字符放到 del 参数中
string.upper() 转换 string 中的小写字母为大写
string.zfill(width) 返回长度为 width 的字符串,原字符串 string 右对齐,前面填充0
string.isdecimal() isdecimal()方法检查字符串是否只包含十进制字符。这种方法只存在于unicode对象。

格式化字符串

[编辑]

%格式化

[编辑]

python2.6之前,沿用C语言的输出格式,使用 % 格式化字符串。

name = 'xiaoming'
age = 12
print("My name is %s, my age is %d" % (name, age))

student_no = 100
# %06d 含义:如果不到6位,则用0在前边占位,超过或等于6位则正常显示。
print("我的学号是: %06d" % student_no)  # 000100

#支持使用字典的形式:
print('Hello[%(name)s],id=%(name)s' % {'id': 10, 'name': 'World'})

str.format方法格式化

[编辑]

python2.6新增format格式化字符串方法。相比%格式化,有如下优点:

  • 单个参数可以多次输出,参数顺序可以不相同,填充方式灵活。
  • 对齐方式强大。
print("...{索引}, ..., {索引}, ...".format(值1, 值2))
print("...{key1}, ..., {key2}, ...".format(key1=value, key2=value))
name = 'xiaoming'
age = 12
# 索引{}为空,默认按照顺序取值:
print('My name is {}, my age is {}'.format(name, age))
print('My name is {0}, my age is {1}'.format(name, age))
print('My name is {name}, my age is {age}'.format(name, age=12))

#填充对齐
# 先取到值,然后在冒号后设定格式:{索引:[填充字符][对齐方式][宽度]}
# 例如  *<20  表示左对齐,共20个字符,用*号填充
print('{0:*<20}'.format('hellopython'))
# 例如 *>20 表示右对齐,总共20个字符,用*号填充
print('{0:*>20}'.format('hellopython'))
# 例如*^20 表示居中显示,总共20个字符,不够用的*号填充
print('{0:*^20}'.format('hellopython'))
#输出:
#hellopython*********
#*********hellopython
#****hellopython*****

# 位数与进制转换
# 保留2位有效数字
print('{:.2f}'.format(3.1415926))
# 转成二进制
print('{0:b}'.format(16))
# 转成八进制
print('{0:o}'.format(10))
# 转成十六进制
print('{0:x}'.format(15))

print('{:0<20.4f}'.format(3.1415926)) # 结果为3.141600000000000000

f-string

[编辑]

python3.6引入了f-string,比str.format使用简单,而且效率也更高。f-string是字符串前面加上f,{}直接使用变量、表达式等。

name = 'xiaoming'
age = 12
# {}中直接使用变量
print(f"My name is {name}, my age is {age}")
# {}中运行表达式
print(f'{1+2+3}')
# 调用 python 内置函数
print(f'{name.upper()}')
# 用 lambda 匿名函数:可以做复杂的数值计算
fun = lambda x : x+1
print(f'{fun(age)}')
# 输出
# My name is xiaoming, my age is 12
# 6
# XIAOMING
# 13

字符串格式化时冒号右侧的形式规则

[编辑]
format_spec     ::=  [[fill]align][sign][#][0][width][grouping_option][.precision][type]
fill            ::=  <any character>
align           ::=  "<" | ">" | "=" | "^"
sign            ::=  "+" | "-" | " "
width           ::=  digit+
grouping_option ::=  "_" | ","
precision       ::=  digit+
type            ::=  "b" | "c" | "d" | "e" | "E" | "f" | "F" | "g" | "G" | "n" | "o" | "s" | "x" | "X" | "%"

说明:

  • align中的=,表示把填充字符放在符号之后,数字之前
  • 符号分别表示:+会在正数前添加+号,-会在负数前添加-号, 空格会在正数前添加空格。
  • #表示在十六进制、八进制、二进制整数前添加0x(或0X)、0o、0b
  • 0表示对最小域宽前补零
  • grouping_option为千分位的分隔符
  • precision为浮点数的小数位数
  • type中,整数可用d(或为空)、b、o、x、X,浮点数可用%(百分数)、e、E、f、F、g、G

提示与技巧

[编辑]

字符串连接操作(加法)是代价高昂的。使用百分号格式化或者str.join()做连接操作。但这是在字符串长度超过500-1000字符时才成立 [1]

print "Spam" + " eggs" + " and" + " spam"               # DON'T DO THIS
print " ".join(["Spam","eggs","and","spam"])            # Much faster/more common Python idiom
print "%s %s %s %s" % ("Spam", "eggs", "and", "spam")   # Also a pythonic way of doing it - very fast

参考文献

[编辑]
  1. 'concat vs join - followup' on 'Python Rocks! and other rants 27.8.2004 Weblog of Kent S Johnson'(2004年8月27日).於2008年8月29日查閱.