文章大纲
字符串是序列的一种,所以标准的序列操作对于字符串也是有用的,但是字符串是不可变的。
设置字符串的格式
str
提供了一个 format()
方法用于字符串的格式化,在字符串中需要替换的内容使用 { }
来指定,例如:
"Have a nice day! {name}".format(name='imxcai')
'Have a nice day! imxcai'
在使用 format()
进行格式化时,可以指定以下部分(这些部分都是可选的):
- 字段名 :用于索引或标识,指出要替换的指定部分
- 转换标志 :跟在叹号(!)后面的单个字符,使用指定的函数将对象转换为字符串
- 格式说明符 :跟在冒号(:)后面的表达式,能够详细的指定最终的格式
字段名
默认情况下,字段名可以省略,此时会按照顺序进行替换,如:
"Today is {}, I'll go to {}".format('monday', 'office')
"Today is monday, I'll go to office"
如果需要替换的位置较多很容易混淆,不好维护,这时可以使用字段:
"Today is {week}, I'll go to {place}".format(week="monday", place="office")
"Today is monday, I'll go to office"
字段名不单单是引用值,它可以像执行 Python 代码一样可以使用其它数据结构或类中的方法或值:
fullname = ['Bob', 'Steve']
"Mr {name[1]}".format(name=fullname)
'Mr Steve'
import math
tmpl = "The {mod.__name__} module defines the valus {mod.pi} for pi"
tmpl.format(mod=math)
'The math module defines the valus 3.141592653589793 for pi'
是不是很类似与 Bash 中的命令替换?
转换标志
如果不想直接替换字符串,而是需要转换格式,可以使用转换标志。转换标志是以 !
标识。
print("{text!s} -- {text!r} -- {text!a}".format(text='hi'))
hi -- 'hi' -- 'hi'
import datetime
today = datetime.datetime.now()
print("{today!s}\n{today!r}\n{today!a}".format(today=today))
2023-11-27 15:23:12.893245
datetime.datetime(2023, 11, 27, 15, 23, 12, 893245)
datetime.datetime(2023, 11, 27, 15, 23, 12, 893245)
使用的标志:
- s 使用
str
进行转换 - r 使用
repr
进行转换 - a 使用
ascii
进行转换
格式说明符
可以指定要转换的值是哪种类型,例如提供的是一个整数,需要格式化为浮点数进行处理:
"number is {num}".format(num=33)
'number is 33'
"number is {num:f}".format(num=33)
'number is 33.000000'
f
默认的精度是6。
说明符参考:
类型 | 用途 |
---|---|
b | 将整数表示为二进制数 |
c | 将证书解读为 Unicode 码点 |
d | 将整数视为十进制进行处理,默认说明符 |
e | 使用科学表示法表示小数 |
E | 使用科学表示法来表示指数 |
f | 将小数表示为定点数 |
o | 将整数表示为八进制数 |
x | 将整数表示为十六进制小写字母 |
X | 将整数表示为十六进制大写字母 |
% | 将数表示为百分比 |
宽度、精度和千位分隔符
设置浮点数 f
格式时,默认在小数点后面显示 6 位小时,且不填充,可以在格式说明中指定宽度可精度。
宽度:
"{num:10}".format(num=5)
' 5'
"{pi:10}".format(pi=math.pi)
'3.141592653589793'
精度:
"{num:10.2f}".format(num=5)
' 5.00'
"{pi:10.2f}".format(pi=math.pi)
' 3.14'
使用 ,
添加前为分隔符:
"number: {:,}".format(1000**5)
'number: 1,000,000,000,000,000'
符号、对齐和用 0 填充
为了能够打印漂亮的格式可以对格式进行对齐填充操作。
在指定宽度和精度的数前面添加一个标识:
- 0 代表填充 0
- < 代表右对齐
- > 代表左对齐
- ^ 代表居中对齐
print('{0:<10.2f}\n{0:^10.2f}\n{0:>10.2f}'.format(math.pi))
3.14
3.14
3.14
可以指定填充字符,而不是默认的空格:
print('{0:$^15}'.format('Title'))
$$$Title$$$
使用说明符 = 可以指定填充的字符放在符号和数字之间:
print('{0:10.2f}\n{1:10.2f}'.format(math.pi, -math.pi))
3.14
-3.14
print('{0:10.2f}\n{1:=10.2f}'.format(math.pi, -math.pi))
3.14
- 3.14
格式化字符串示例
尝试按照以下图片格式化输出漂亮的格式。
代码:
width = 50
value_width = 20
item_width = width - value_width
print('=' * width)
# if width=50 return {:30}{:>20}
header_fmt = '{{:{}}}{{:>{}}}'.format(item_width, value_width)
# if width=50 return {:30}{:>20}
fmt = '{{:{}}}{{:>{}}}'.format(item_width, value_width)
data = {'车号': 'BA07623', '证号': '9000117298', '日期': '2023-11-26',
'上车': '18:56', '下车': '19:43'}
print(header_fmt.format('Item', 'Value'))
print('-' * width)
for k in data:
print(fmt.format(k, data[k]))
print('=' * width)
执行效果:
==================================================
Item Value
--------------------------------------------------
车号 BA07623
证号 9000117298
日期 2023-11-26
上车 18:56
下车 19:43
==================================================
字符串方法
字符串的方法很多都是从模块 string
中继承而来的,string
定义很多常量,可以非常方便的调用:
- string.digits 包含0-9的字符串
- string.ascii_letters 包含所有 ASCII 字符大写和小写的字符串
- string.ascii_lowercase 包含所有小写的 ASCII 字母的字符串
- string.ascii_uppercase 包含所有大写的 ASCII 字母的字符串
- string.printable 包含所有可打印的 ASCII 字符的字符串
str 中的方法
可以直接对字符串使用 str
中的方法。
center
通过在两边添加填充字符,让字符串居中:
'TITLE'.center(50)
' TITLE '
'TITLE'.center(50,'-')
'----------------------TITLE-----------------------'
find
在字符串中查找子串,找到返回第一个子串中的第一个字符索引,否则返回 -1
:
'student@student.lab.example.com'.find('student')
0
'student@student.lab.example.com'.find('lab')
16
'student@student.lab.example.com'.find('mail')
-1
find
方法默认从头到尾进行搜索,可以指定范围:
'student@student.lab.example.com'.find('student', 7)
8
'student@student.lab.example.com'.find('student', 7, 30)
8
join
join
用于合并序列元素:
seq = [1,2,3,4,5]
sep = '-'
sep.join(seq)
Traceback (most recent call last):
File "<pyshell#126>", line 1, in <module>
sep.join(seq)
TypeError: sequence item 0: expected str instance, int found
seq=['1', '2', '3', '4', '5']
sep.join(seq)
'1-2-3-4-5'
join
接受对象为序列的数据,同时合并的所有元素类型应为字符串。
split
split
与 join
相反,用于将字符串拆分为序列:
'1-2-3-4-5'.split('-')
['1', '2', '3', '4', '5']
lower
lower
方法返回字符串的小写格式:
'Hello WORLD'.lower()
'hello world'
replace
指定字串都替换成另一个字符串,并返回替换后的结果:
'This is demo'.replace('is', 'ez')
'Thez ez demo'
strip
将字符串开头和末尾的空白删除,并返回删除后的结果:
' TITLE '.strip()
'TITLE'
' TITLE '.rstrip()
' TITLE'
' TITLE '.lstrip()
'TITLE '
translate
translate
和 replace
一样替换字符串的特定部分,但它只能进行单字符替换,优势是能同时替换多个字符,效率较高。
使用 translate
替换之前必须先创建一个转换表:
table = str.maketrans('is', 'ez')
table
{105: 101, 115: 122}
table 中记录了 Unicode 码点之间的映射,随后可以作为 translate
的参数。
'This is demo'.translate(table)
'Thez ez demo'
判断字符串是否满足特定的条件
字符串中以 is
开头的方法基本都是判断字符串是否具有特定的性质,如果具备返回 True
否则返回 False
。
方法有:isalnum 、 isalpha 、 isdecimal 、 isdigit 、 isidentifier 、 islower 、 isnumeric 、
isprintable、isspace、istitle、isupper