Python进阶:字符串
- Python进阶:字符串
- 1. 字符串简介
- 2. 字符串编码
- 3. 转义字符
- 4. 字符串格式化
- 5. 字符串常用方法与操作
- find()、rfind()、index()、rindex()、count()
- split()、rsplit()、partition()、rpartition()
- 符串连接join()
- lower()、upper()、capitalize()、title()、swapcase()
- replace()、maketrans()、translate()
- strip()、rstrip()、lstrip()
- startswith()、endswith()
- isalnum()、isalpha()、isdigit()、isspace()、isupper()、islower()
- center()、ljust()、rjust()
- 字符串对象支持的运算符
- 适用于字符串对象的内置函数
- 字符串切片
- 字符串常量
Python进阶:字符串
1. 字符串简介
在Python中,字符串属于不可变有序序列,使用单引号、双引号、三单引号或三双引号作为定界符,并且不同的定界符之间可以互相嵌套。
'abc'、'123'、'中国'
"Python"
'''Tom said,"Let's go"'''
除了支持序列通用方法(包括双向索引、比较大小、计算长度、元素访问、切片、成员测试等操作)以外,字符串类型还支持一些特有的操作方法,例如字符串格式化、查找、替换、排版等等。
字符串属于不可变序列,不能直接对字符串对象进行元素增加、修改与删除等操作,切片操作也只能访问其中的元素而无法使用切片来修改字符串中的字符。
2. 字符串编码
最早的字符串编码是美国标准信息交换码ASCII,仅对10个数字、26个大写英文字母、26个小写英文字母及一些其他符号进行了编码。ASCII码采用1个字节来对字符进行编码,最多只能表示256个符号。
GB2312是我国制定的中文编码,使用1个字节表示英语,2个字节表示中文;GBK是GB2312的扩充,而CP936是微软在GBK基础上开发的编码方式。GB2312、GBK和CP936都是使用2个字节表示中文。
UTF-8对全世界所有国家需要用到的字符进行了编码,以1个字节表示英语字符(兼容ASCII),以3个字节表示中文,还有些语言的符号使用2个字节(例如俄语和希腊语符号)或4个字节。
不同编码格式之间相差很大,采用不同的编码格式意味着不同的表示和存储形式,把同一字符存入文件时,写入的内容可能会不同,在试图理解其内容时必须了解编码规则并进行正确的解码。如果解码方法不正确就无法还原信息,从这个角度来讲,字符串编码也具有加密的效果。
Python 3.x完全支持中文字符,默认使用UTF8编码格式,无论是一个数字、英文字母,还是一个汉字,在统计字符串长度时都按一个字符对待和处理。
>>> s = '中国山东烟台'
>>> len(s) #字符串长度,或者包含的字符个数
6
>>> s = '中国山东烟台ABCDE' #中文与英文字符同样对待,都算一个字符
>>> len(s)
11
>>> 姓名 = '张三' #使用中文作为变量名
>>> print(姓名) #输出变量的值
张三
3. 转义字符
# 转义字符用法
>>> print('Hello\nWorld') #包含转义字符的字符串
Hello
World
>>> print('\101') #三位八进制数对应的字符
A
>>> print('\x41') #两位十六进制数对应的字符
A
>>> print('我是\u8463\u4ed8\u56fd')#四位十六进制数表示Unicode字符
我是董付国
# 为了避免对字符串中的转义字符进行转义,可以使用原始字符串,在字符串前面加上字母r或R表示原始字符串,其中的所有字符都表示原始的含义而不会进行任何转义。
>>> path = 'C:\Windows\notepad.exe'
>>> print(path) #字符\n被转义为换行符
C:\Windows
otepad.exe
>>> path = r'C:\Windows\notepad.exe' #原始字符串,任何字符都不转义
>>> print(path)
C:\Windows\notepad.exe
4. 字符串格式化
4.1 使用%运算符进行格式化
常用格式字符
>>> x = 1235
>>> so = "%o" % x
>>> so
"2323"
>>> sh = "%x" % x
>>> sh
"4d3"
>>> se = "%e" % x
>>> se
"1.235000e+03"
>>> chr(ord("3")+1)
"4"
>>> "%s" % 65
"65"
>>> "%s" % 65333
"65333"
4.2 使用format()方法进行格式化
>>> 1/3
0.3333333333333333
>>> print('{0:.3f}'.format(1/3)) #保留3位小数
0.333
>>> '{0:%}'.format(3.5) #格式化为百分数
'350.000000%'
>>> '{0:_},{0:_x}'.format(1000000) #Python 3.6.0及更高版本支持
'1_000_000,f_4240'
>>> '{0:_},{0:_x}'.format(10000000) #Python 3.6.0及更高版本支持
'10_000_000,98_9680'
>>> print("The number {0:,} in hex is: {0:#x}, the number {1} in oct is {1:#o}".format(5555,55))
The number 5,555 in hex is: 0x15b3, the number 55 in oct is 0o67
>>> print("The number {1:,} in hex is: {1:#x}, the number {0} in oct is {0:o}".format(5555,55))
The number 55 in hex is: 0x37, the number 5555 in oct is 12663
>>> print("my name is {name}, my age is {age}, and my QQ is {qq}".format(name = "Dong Fuguo",age = 40,qq = "30646****"))
my name is Dong Fuguo, my age is 40, and my QQ is 30646****
>>> position = (5, 8, 13)
>>> print("X:{0[0]};Y:{0[1]};Z:{0[2]}".format(position))
X:5;Y:8;Z:13
4.3 格式化的字符串常量
从Python 3.6.x开始支持一种新的字符串格式化方式,官方叫做Formatted String Literals,在字符串前加字母f,含义与字符串对象format()方法类似.
>>> name = 'Dong'
>>> age = 39
>>> f'My name is {name}, and I am {age} years old.'
'My name is Dong, and I am 39 years old.'
>>> width = 10
>>> precision = 4
>>> value = 11/3
>>> f'result:{value:{width}.{precision}}'
'result: 3.667'
5. 字符串常用方法与操作
Python字符串对象提供了大量方法用于字符串的切分、连接、替换和排版等操作,另外还有大量内置函数和运算符也支持对字符串的操作。
字符串对象是不可变的,所以字符串对象提供的涉及到字符串“修改”的方法都是返回修改后的新字符串,并不对原始字符串做任何修改,无一例外。
find()、rfind()、index()、rindex()、count()
find()和rfind方法分别用来查找一个字符串在另一个字符串指定范围(默认是整个字符串)中首次和最后一次出现的位置,如果不存在则返回-1;
index()和rindex()方法用来返回一个字符串在另一个字符串指定范围中首次和最后一次出现的位置,如果不存在则抛出异常;
count()方法用来返回一个字符串在当前字符串中出现的次数。
>>> s="apple,peach,banana,peach,pear"
>>> s.find("peach")
6
>>> s.find("peach",7)
19
>>> s.find("peach",7,20)
-1
>>> s.rfind('p')
25
>>> s.index('p')
1
>>> s.index('pe')
6
>>> s.index('pear')
25
>>> s.index('ppp')
Traceback (most recent call last):
File "<pyshell#11>", line 1, in <module>
s.index('ppp')
ValueError: substring not found
>>> s.count('p')
5
>>> s.count('pp')
1
>>> s.count('ppp')
0
split()、rsplit()、partition()、rpartition()
split()和rsplit()方法分别用来以指定字符为分隔符,把当前字符串从左往右或从右往左分隔成多个字符串,并返回包含分隔结果的列表;
partition()和rpartition()用来以指定字符串为分隔符将原字符串分隔为3部分,即分隔符前的字符串、分隔符字符串、分隔符后的字符串,如果指定的分隔符不在原字符串中,则返回原字符串和两个空字符串。
>>> s = "apple,peach,banana,pear"
>>> s.split(",")
["apple", "peach", "banana", "pear"]
>>> s.partition(',')
('apple', ',', 'peach,banana,pear')
>>> s.rpartition(',')
('apple,peach,banana', ',', 'pear')
>>> s.rpartition('banana')
('apple,peach,', 'banana', ',pear')
>>> s = "2017-10-31"
>>> t = s.split("-")
>>> print(t)
['2017', '10', '31']
>>> print(list(map(int, t)))
[2017, 10, 31
# split()和rsplit()方法还允许指定最大分割次数。
>>> s = '\n\nhello\t\t world \n\n\n My name is Dong '
>>> s.split(None, 1)
['hello', 'world \n\n\n My name is Dong ']
>>> s.rsplit(None, 2)
['\n\nhello\t\t world \n\n\n My name', 'is', 'Dong']
>>> s.split(maxsplit=6)
['hello', 'world', 'My', 'name', 'is', 'Dong']
>>> s.split(maxsplit=100) #最大分隔次数大于可分隔次数时无效
['hello', 'world', 'My', 'name', 'is', 'Dong']
# 对于split()和rsplit()方法,如果不指定分隔符,则字符串中的任何空白符号(空格、换行符、制表符等)都将被认为是分隔符,把连续多个空白字符看作一个分隔符。
>>> s = 'hello world \n\n My name is Dong '
>>> s.split()
['hello', 'world', 'My', 'name', 'is', 'Dong']
>>> s = '\n\nhello world \n\n\n My name is Dong '
>>> s.split()
['hello', 'world', 'My', 'name', 'is', 'Dong']
>>> s = '\n\nhello\t\t world \n\n\n My name\t is Dong '
>>> s.split()
['hello', 'world', 'My', 'name', 'is', 'Dong']
# 然而,明确传递参数指定split()使用的分隔符时,情况是不一样的。
>>> 'a,,,bb,,ccc'.split(',') #每个逗号都被作为独立的分隔符
['a', '', '', 'bb', '', 'ccc']
>>> 'a\t\t\tbb\t\tccc'.split('\t') #每个制表符都被作为独立的分隔符
['a', '', '', 'bb', '', 'ccc']
>>> 'a\t\t\tbb\t\tccc'.split() #连续多个制表符被作为一个分隔符
['a', 'bb', 'ccc']
符串连接join()
>>> li = ["apple", "peach", "banana", "pear"]
>>> ','.join(li)
'apple,peach,banana,pear'
>>> '.'.join(li)
'apple.peach.banana.pear'
>>> '::'.join(li)
'apple::peach::banana::pear'
lower()、upper()、capitalize()、title()、swapcase()
>>> s = "What is Your Name?"
>>> s.lower() #返回小写字符串
'what is your name?'
>>> s.upper() #返回大写字符串
'WHAT IS YOUR NAME?'
>>> s.capitalize() #字符串首字符大写
'What is your name?'
>>> s.title() #每个单词的首字母大写
'What Is Your Name?'
>>> s.swapcase() #大小写互换
'wHAT IS yOUR nAME?'
replace()、maketrans()、translate()
查找替换replace(),类似于Word中的“全部替换”功能。
>>> s = "中国,中国"
>>> print(s)
中国,中国
>>> s2 = s.replace("中国", "中华人民共和国") #两个参数都作为一个整理
>>> print(s2)
中华人民共和国,中华人民共和国
字符串对象的maketrans()方法用来生成字符映射表,而translate()方法用来根据映射表中定义的对应关系转换字符串并替换其中的字符,使用这两个方法的组合可以同时处理多个字符。
#创建映射表,将字符"abcdef123"一一对应地转换为"uvwxyz@#$"
>>> table = ''.maketrans('abcdef123', 'uvwxyz@#$')
>>> s = "Python is a greate programming language. I like it!"
#按映射表进行替换
>>> s.translate(table)
'Python is u gryuty progrumming lunguugy. I liky it!'
strip()、rstrip()、lstrip()
>>> s = " abc "
>>> s.strip() #删除空白字符
'abc'
>>> '\n\nhello world \n\n'.strip() #删除空白字符
'hello world'
>>> "aaaassddf".strip("a") #删除指定字符
'ssddf'
>>> "aaaassddf".strip("af")
'ssdd'
>>> "aaaassddfaaa".rstrip("a") #删除字符串右端指定字符
'aaaassddf'
>>> "aaaassddfaaa".lstrip("a") #删除字符串左端指定字符
'ssddfaaa'
这三个函数的参数指定的字符串并不作为一个整体对待,而是在原字符串的两侧、右侧、左侧删除参数字符串中包含的所有字符,一层一层地从外往里扒。
>>> 'aabbccddeeeffg'.strip('gbaefcd')
''
startswith()、endswith()
s.startswith(t)、s.endswith(t),判断字符串是否以指定字符串开始或结束
>>> s = 'Beautiful is better than ugly.'
>>> s.startswith('Be') #检测整个字符串
True
>>> s.startswith('Be', 5) #指定检测范围起始位置
False
>>> s.startswith('Be', 0, 5) #指定检测范围起始和结束位置
True
>>> import os
>>> [filename for filename in os.listdir(r'c:\\') if filename.endswith(('.bmp','.jpg','.gif'))]
isalnum()、isalpha()、isdigit()、isspace()、isupper()、islower()
nisalnum()、isalpha()、isdigit()、isspace()、isupper()、islower(),用来测试字符串是否为数字或字母、是否为字母、是否为数字字符、是否为空白字符、是否为大写字母以及是否为小写字母。
>>> '1234abcd'.isalnum()
True
>>> '1234abcd'.isalpha() #全部为英文字母时返回True
False
>>> '1234abcd'.isdigit() #全部为数字时返回True
False
>>> 'abcd'.isalpha()
True
>>> '1234.0'.isdigit()
False
center()、ljust()、rjust()
center()、ljust()、rjust(),返回指定宽度的新字符串,原字符串居中、左对齐或右对齐出现在新字符串中,如果指定宽度大于字符串长度,则使用指定的字符(默认为空格)进行填充。
>>> 'Hello world!'.center(20) #居中对齐,以空格进行填充
' Hello world! '
>>> 'Hello world!'.center(20, '=') #居中对齐,以字符=进行填充
'====Hello world!===='
>>> 'Hello world!'.ljust(20, '=') #左对齐
'Hello world!========'
>>> 'Hello world!'.rjust(20, '=') #右对齐
'========Hello world!'
字符串对象支持的运算符
>>> 'hello ' + 'world'
'hello world'
>>> "a" in "abcde" #测试一个字符中是否存在于另一个字符串中
True
>>> 'ab' in 'abcde'
True
>>> 'ac' in 'abcde' #关键字in左边的字符串作为一个整体对待
False
>>> "j" in "abcde"
False
>>> 'abcd' * 3
'abcdabcdabcd'
适用于字符串对象的内置函数
>>> x = 'Hello world.'
>>> len(x) #字符串长度
12
>>> max(x) #最大字符
'w'
>>> min(x)
' '
>>> list(zip(x,x)) #zip()也可以作用于字符串
[('H', 'H'), ('e', 'e'), ('l', 'l'), ('l', 'l'), ('o', 'o'), (' ', ' '), ('w', 'w'), ('o', 'o'), ('r', 'r'), ('l', 'l'), ('d', 'd'), ('.', '.')]
>>> sorted(x)
[' ', '.', 'H', 'd', 'e', 'l', 'l', 'l', 'o', 'o', 'r', 'w']
>>> list(reversed(x))
['.', 'd', 'l', 'r', 'o', 'w', ' ', 'o', 'l', 'l', 'e', 'H']
>>> list(enumerate(x))
[(0, 'H'), (1, 'e'), (2, 'l'), (3, 'l'), (4, 'o'), (5, ' '), (6, 'w'), (7, 'o'), (8, 'r'), (9, 'l'), (10, 'd'), (11, '.')]
>>> list(map(add, x, x))
['HH', 'ee', 'll', 'll', 'oo', ' ', 'ww', 'oo', 'rr', 'll', 'dd', '..']
# 内置函数eval()用来把任意字符串转化为Python表达式并进行求值。
>>> eval("3+4") #计算表达式的值
7
>>> a = 3
>>> b = 5
>>> eval('a+b') #这时候要求变量a和b已存在
8
>>> import math
>>> eval('math.sqrt(3)')
1.7320508075688772
字符串切片
切片也适用于字符串,但仅限于读取其中的元素,不支持字符串修改。
>>> 'Explicit is better than implicit.'[:8]
'Explicit'
>>> 'Explicit is better than implicit.'[9:23]
'is better than'
>>> path = 'C:\\Python35\\test.bmp'
>>> path[:-4] + '_new' + path[-4:]
'C:\\Python35\\test_new.bmp'
字符串常量
# 使用string模块提供的字符串常量,模拟生成指定长度的随机密码。
from random import choice
from string import ascii_letters, digits
characters = digits + ascii_letters
def generatePassword(n):
return ''.join((choice(characters) for _ in range(n)))
print(generatePassword(8))
print(generatePassword(15))