字符串
字符串笔记整理
1.1. 字符串对象是不可变的
字符串是不可变的
>>> s1="a"
>>> id(s1)
34344888
>>> s1+="b"
>>> id(s1)
38588912
>>> 'a'=='a'
True
>>> 'a' in 'abc'
True
>>> 'a'=='b'
False
>>> 'a'!='b'
True
>>> 'a' is 'a'
True
>>> 'a' is not 'a'
False
1.2. 用id判断字符串的地址
字符串值一样的在内存中是同一个地址
>>> a='a'+'b'
>>> id(a)
2348771931616
>>> id('ab')
2348771931616
>>>
1.3. 字符串的两种类型:str和bytes
只要不是在内存中使用时全部都是bytes类型
>>> s = "abc"
>>> type(s)
<class 'str'>
>>> s = "abc".encode("utf-8")
>>> type(s)#用于网络传输
<class 'bytes'>
不能直接将中文定义为bytes类型
>>> s = b'aaaa'
>>> type(s)
<class 'bytes'>
>>> s= b'中国'
File "<stdin>", line 1
SyntaxError: bytes can only contain ASCII literal characters.
>>> s = '中国'.encode('utf-8')
>>> s = '中国'.encode()
>>> import sys
>>> sys.getdefaultencoding()#判断默认的编码
'utf-8'
1.4. 元字符r/R:表示后面的字符不需要转义
>>> print('1\n2')
1
2
>>> print(r'1\n2')
1\n2
>>> print(R'1\2')
1\2
>>> print('1\2')
1
>>> print('1\\2')#转义
1\2
>>>
1.5. 换行和转义
转义字符 |
描述 |
\(在行尾时) |
续行符,也就是多行语句符 |
\\ |
反斜杠符号 |
\’ |
单引号 |
\" |
双引号 |
\a |
响铃 |
\b |
退格(Backspace) |
\e |
转义 |
\000 |
空(不可见字符) |
\n |
换行(不可见字符) |
\v |
纵向制表符(不可见字符) |
\t |
横向制表符(不可见字符) |
\r |
回车(不可见字符) |
\f |
换页(不可见字符) |
\oyy |
八进制数yy代表的字符,例如:\o12代表换行 |
\xyy |
十进制数yy代表的字符,例如:\x0a代表换行 |
\other |
其它的字符以普通格式输出 |
不同平台下的换行符:
window:
>>> import os
>>> os.linesep
'\r\n'
>>>
linu/mac:
>>> import os
>>> os.linesep
'\n'
打印单引号
>>> print("'")
'
>>> print('\'')
'
1.6. 字符串格式化
1.6.1. %格式化输出:
符号 |
描述 |
%c |
%c 格式化字符及其ASCII码 |
%s |
%s 格式化字符串 |
%d |
%d 格式化整数 |
%u |
%u 格式化无符号整型,和%d一致 |
%o |
%o 格式化无符号八进制数 |
%x |
%x 格式化无符号十六进制数 |
%X |
%X 格式化无符号十六进制数(大写) |
%f |
格式化浮点数,可指定小数点后的位数,默认保留小数点后6位 |
%e |
%e 用科学计数法格式化浮点数 |
%E |
%E 作用同%e,用科学计数法格式化浮点数 |
%g |
%g %f 和%e的简写 |
%G |
%G %f 和 %E的简写 |
%p |
%p 用十六进制数格式化变量的地址 |
>>> '%s=%s'%(1,2)
'1=2'
>>> '%d=%d'%(1,2)
'1=2'
>>> '%d=%d'%('a',2)#不是数字会报错
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: %d format: a number is required, not str
>>> '%.2f=%.2f'%(1,2)#保留小数点后两位
'1.00=2.00'
>>> '%.2f=%.2f'%(1.9999,2.5555) #会四舍五入
'2.00=2.56'
name = 'ruby'
#格式化字符串
print ("My name is %s and \ weight is %d kg" %(name, 21))
1.6.2. 模板格式化
>>> from string import Template
>>> s = Template('There are ${key1} ${key2} Quotations Symbols')
>>> print (s.substitute(key2='Python', key1=3))
There are 3 Python Quotations Symbols
1.7. 字符串常用方法:
1.7.1. strip()/lstrip()/rstrip():去掉空白字符
用法:S.strip([chars])
作用:去掉字符串左右的空白字符(\r、\t、\n、\f、空格),并返回处理后的结果,原始的字符串并未改变
说明:不带参数的strip()函数,表示把S中前后所有的空白字符全部去掉,包 括’\n’ , ‘\t’ , ‘\r’ , ’ ’ 等不可见字符串,可以理解为把S前后空白字符串替换为None;带参数的strip()函数表示将S前后指定字符串chars去掉。
lstrip()和rstrip()分别为去除左侧或右侧的空白字符
>>> "****abc******".strip("*")
'abc'
>>> "****abc******".strip("*#")#里面有的都可以去除
'abc'
>>> "###****abc******####".strip("*#")
'abc'
>>> "###*** *abc******####".rstrip('*#')
'###*** *abc'
>>> "###*** *abc******####".lstrip('*#')
' *abc******####'
>>> " \t\nabc ".strip()
'abc'
>>> " \t\nabc ".lstrip()
'abc \t'
>>> " \t\nabc ".rstrip()
' \t\t\nabc'
''.join([chr(i) for i in range(97,123)])#快速的生成全部的小写字母
1.7.2. upper()/lower()/swapcase():大小写转换及互换
>>> 'aC'.upper()
'AC'
>>> 'aC'.lower()
'ac'
>>> '1'.lower()#数字也可以执行lower或upper,不过没什么意义
'1'
>>> 'aC'.swapcase()
'Ac'
>>> "abc bcd".swapcase()
'ABC BCD'
>>> "Bbc bCD".swapcase()
'bBC Bcd'
1.7.3. capitalize():将第1个单词首字母大写
>>> 'and python'.capitalize()
'And python'
1.7.4. title():将所有单词首字母大写
>>> "abc bcd".title()
'Abc Bcd'
>>> string.capwords("abc bcd")
'Abc Bcd'
注意:capwords和title的作用相同,只不过在string模块中
1.7.5. ljust()/rjust()/center():左、右、居中对齐
s.ljust(width,[fillchar])
作用:输出width个字符,S左对齐,不足部分用fillchar填充,默认为空格。
>>> 'abc'.ljust(10)
'abc '
>>> 'abc'.rjust(10)
' abc'
>>> 'abc'.center(10)
' abc '
>>>
ljust()、rjust()、center()
>>> "abc".ljust(10)
'abc '
>>> "abc".ljust(10,"*")
'abc*******'
>>> "abc".rjust(10,"*")
'*******abc'
>>> "abc".center(10,"*")
'***abc****'
>>> "abc".center(10,"**")#只能是一个字符
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: The fill character must be exactly one character long
>>>
所有的标点符号
>>> import string
>>> string.punctuation
'!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~'
去掉字符串中的标点:
list(map(lambda x:x.strip(string.punctuation),"I am a boy, you r a girl! yes
!".split()))
1.7.6. zfill():填充
用法:S.zfill(width)
作用:把S变成width长,并在右对齐,不足部分用0补足
>>> '123'.zfill(10)
'0000000123'
>>> '1234'.zfill(1)
'1234'
1.7.7. find()/rfind():查找子字符串的位置
在指定字符串范围内查找子字符串第一次出现的位置
用法:s.find(substr, [start, [end]]) /s.rfind(substr, [start, [end]])
作用:返回s中出现substr的第一个字母的标号,如果s中没有substr则返回 -1。start和end作用就相当于在s[start:end]中搜索 (注意是开区间)
>>> '1234'.find('5')
-1
>>> '1234'.find('3')
2
>>> '1234'.find('3',0)
2
>>> '1234'.find('3',0,1)
-1
>>> '1234'.find('3',3)
-1
>>> '123334'.find('3',2)
2
>>> '1234'.find('4',1,3)#开区间
-1
>>> '4234'.rfind('4')#从右侧开始查找
3
1.7.8. index()/rindex():查找子字符串的位置
可在指定字符串范围内查找子字符串出现的位置,找不到则返回错误
用法:s.index(substr, [start, [end]])/s.rindex(substr, [start, [end]])#开区间
作用:与find()相同,只是在s中没有substr时,会返回一个运行时错误
>>> '1234'.index('3')
2
>>> '1234'.index('5')#运行时错误
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: substring not found
1.7.9. replace()/expandtabs():替换字符串的指定内容
用法:s.replace(oldstr, newstr, [count])
作用:把s中的oldstar替换为newstr,count 为替换次数。还有 一些函数进行特殊字符的替换
>>> "abca".replace('bc','xxxx')
'axxxxa'
>>> "abca".replace('a','xxxx')
'xxxxbcxxxx'
>>> "abca".replace('a','xxxx',1)
'xxxxbca'
>>> "abc def ane 222".replace(' ','') #相当于删除空格
'abcdefane222'
>>>
expandtabs()
用法:s.expandtabs([tabsize])
作用:将tab替换为指定的空格数量,把s中的tab字符替换为空格,每个tab替换为tabsize个空格,默认是8个
>>> '1 2 3'.expandtabs(1)
'1 2 3'
>>> '1 2 3'.expandtabs()
'1 2 3'
1.7.10. split()/rsplit()/splitlines():默认用空白字符切割
用法:s.split([sep, [maxsplit]])
作用:以sep为分隔符,把S分成一个list,maxsplit表示分割的次
数。默认的分割符为空白字符
>>> 'a b \nd\re'.split()
['a', 'b', 'd', 'e']
>>> 'a*b*c*d**E'.split('*')
['a', 'b', 'c', 'd', '', 'E']
>>> 'a*b*c*d**E'.split('*',1)
['a', 'b*c*d**E']
>>> 'a*b*c*d**E'.rsplit('*',1)
['a*b*c*d*', 'E']
splitlines():
用法:s.splitlines([keepends])
作用:按照行分隔符分为一个list,keepends是一个bool值,如果为真每行后而会保留行分割符。
>>> s='1\n2\n'
>>> print (s.splitlines(True))
['1\n', '2\n']
>>> print (s.splitlines())
['1', '2']
>>> print (s.splitlines(1))#按行分隔符分隔,且保留行分隔符
['1\n', '2\n']
1.7.11. join():字符串连接
将列表/元组拼接为字符串,列表/元组中的必须为字符
>>> '*'.join([1,2,3])#不是字符会报错
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: sequence item 0: expected str instance, int found
>>> '*'.join(['1','2','3'])
'1*2*3'
>>> '*'.join(('1','2','3'))#也可以是元组
'1*2*3'
1.7.12. startswith()/endswith()/in:开头、结尾是否存在
判断字符串是否以某个字符串为开头或结尾
>>> "abc".startswith("a")
True
>>> "abc".endswith("c")
True
>>> "abc".startswith("c")
False
>>> "abc".endswith("a")
False
>>> 'a' in 'abc'
True
>>> 'a' is 'a'
True
>>> 'a'=='a'
True
>>> 'a'!='a'
False
>>>
1.7.13. isalpha():是否全部为字母
作用:如果字符串中所有的字符都是由字母组成,并且至少有一个字符,返回True,否则返False。
>>> "abc".isalpha()
True
>>> "abc1".isalpha()
False
1.7.14. isalnum():是否为数字或字母
作用:如果字符串中所有的字符都是由数字或字母组成,并且至少有一个字符,返回True,否则返False。
>>> 'abcd'.isalnum()
True
>>> '1'.isalnum()
True
>>> '1sdns2'.isalnum()
True
>>> '1 2'.isalnum()
False
1.7.15. isdigit():是否全部为数字
作用:如果字符串中所有的字符都是由数字组成,并且至少有一个字符,返回True,否则返False。
>>> "abc1".isdigit()
False
>>> "341".isdigit()
True
>>> "31.25".isdigit()#有小数点不行
False
1.7.16. isspace():是否为空格
作用:如果字符串中所有的字符都是由空格组成,并且至少有一个字符,返回True,否则返False。
>>> ''.isspace()
False
>>> ' '.isspace()
True
1.7.17. islower()/isupper()是否为大写或小写
>>> '13abc'.islower()
True
>>> '13ASD'.isupper()#数字会忽略
True
1.7.18. istitle():
作用:检测字符串中所有的单词首字母是否为大写字母,其他为小写字母,并且z字符串中至少有一个字母,则返回True,否则返回False。
>>> 'Apple is good'.istitle()
False
>>> 'Apple Is Good'.istitle()
True
>>> 'A'.istitle()
True
>>> "Today Is 21 Fine Day".istitle()
True
>>>
1.7.19. maketrans()/translate():字符串映射
用法:str.maketrans(from, to)
作用:返回一个256个字符组成的翻译表,其中from中的字符被一一对应地转换成to,所以from和to必须是等长的。
用法:s.translate(table[,deletechars])
作用:使用上面的函数产后的翻译表,把S进行翻译,并把deletechars中有的字符删掉。需要注意的是,如果s必须为字节字符串,否则unicode字符串,不支持 deletechars参数
>>> map = str.maketrans('123', 'abc')
>>> s = '54321123789'
>>> print (s.translate(map))
54cbaabc789
>>> print (s.translate(map,'123'))#unicode字符串不支持删除
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: translate() takes exactly one argument (2 given)
>>> t=bytes.maketrans(b'abc',b'ABC')
>>> print (b'abc123'.translate(t,b"123"))#必须是bytes字符串才能删除
b'ABC'
>>> print (b'abc321'.translate(t,b"123"))
b'ABC'
1.7.20. 字符的编码和解码
>>> '中国'.encode('gbk')
b'\xd6\xd0\xb9\xfa'
>>> '中国'.encode('gbk').decode('gbk')
'中国'
>>> import chardet
>>> chardet.detect('中国人民从此富裕起来了'.encode('gbk'))
{'encoding': 'GB2312', 'confidence': 0.99, 'language': 'Chinese'}
>>> "中国".encode("gbk")
b'\xd6\xd0\xb9\xfa'
>>> s = b'\xd6\xd0\xb9\xfa'
>>> s #直接打印输出的还是
b'\xd6\xd0\xb9\xfa'
>>> s.decode('gbk')
'中国'
>>> import base64
>>> encodestr = base64.b64encode(b'I love you')
>>> print(encodestr)
b'SSBsb3ZlIHlvdQ=='
>>> print(base64.b64decode(encodestr))
b'I love you'
1.7.21. chr/ord:字符和ascii码转换
py2只能是ascii码,py3可以是中文,但是只能是一个
>>> ord('中')
20013
>>> chr(20013)
'中'
中文的ascii码:
>>> s = '中'
>>> repr(s)
"'中'"
>>> ord(s)
20013
>>> chr(10015)
'✟'
>>> chr(10016)
'✠'
>>> chr(20016)
'丰'
>>> chr(20015)
'丯'
>>> chr(20017)
'丱'
>>>
1.7.22. count():统计字符中元素出现的个数
用法:s.count(substr, [start, [end]])
作用:计算substr在s[start, [end]]中出现的次数
>>> 'abddddddnalendd'.count('d')
8
>>> 'abddddddnalendd'.count('a')
2
>>> s = 'boy boy boy'
>>> s.count('b',3)
2
>>> s.count('b',3,6)
1
1.7.23. +操作符效率不高,可以用以下方法代替:
join()或format()
join():
>>> ''.join(['a','b'])
'ab'
format:
>>> 'abc{}'.format('x')
'abcx'
>>> 'abc{1}{0}'.format('x','y')
'abcyx'
1.7.24. string模块
>>> import string
>>> string.ascii_lowercase
'abcdefghijklmnopqrstuvwxyz'
>>> string.ascii_uppercase
'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
>>> string.punctuation
'!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~'
>>> string.ascii_letters
'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
>>> string.digits
'0123456789'
1.8. 课堂练习:
1.8.1. 字符串加密
'''1、将"gloryroad"按照如下规则进行加密:
字母对应的asscii码值进行加密,并且在码值前面加上码值长度
如g对应的码值为ord("g")=103,则字母g加密结果为3103
3是ascii的长度。
“gloryroad”正确输出加密结果为:
"31033108311131143121311431112973100"'''
#encoding=utf-8
s='gloryroad'
result=[]
for i in s:
result.append(str(len(str(ord(i))))+str(ord(i)))
cipher=''.join(result)
print(cipher)
1.8.2. 将上题中的加密字符串进行解密
'''方法有2种:
方法:1 种用while循环,观察加密后的规律,想办法遍历所有的内容
方法2: 递归实现'''
#while循环
result=[]
temp = cipher[:]
while len(temp)>0:
a = temp[1:int(temp[0])+1]
result.append(chr(int(a)))
temp=temp[int(temp[0])+1:]
print(''.join(result))
#while方法二:吴老师版本
def decode_str(s):
index = 0 #每个字母的acsii码的长度
decoded_str = ""
while index < len(s):
decoded_str+= chr(int(s[(index+1):(index+int(s[index])+1)]))
index = index+int(s[index])+1
return decoded_str
#递归
'''
1.自己调用自己的逻辑写清楚
2.要有结束递归的条件
'''
def decrypt(s,result=[]):
if len(s)==0:
return ''.join(result)
else:
result.append(chr(int(s[1:int(s[0])+1])))
return decrypt(s[int(s[0])+1:])
print(decrypt(cipher))
#递归:吴老师版本
decrypt_result=""
def get_data(data):
global decrypt_result
if len(data)==0:
print("解密结果为:"+decrypt_result)
else:
num=int(data[0])
decrypt_result+=chr(int(data[1:(num+1)]))
get_data(data[(num+1):])
1.8.3. '''统计一个字符串中包含a的单词有几个'''
s='I am a boy!'
#方法一:遍历
result =0
for i in s.split():
if i[0]=='a':
result+=1
print(result)
#方法二:正则
print(len(re.findall(r'\ba\w*\b',s)))
1.8.4. '''将字符串中反转'''
s='I am a boy!'
print(''.join(s.split())[::-1])
print(" ".join(list(map(lambda x:x[::-1],s.split()[::-1]))))
1.8.5. '''找到所有出现的字符串'''
#方法1:
s="abbaaba"
result = []
for i in range(len(s)):
if s[i:i+2] == "ab":
result.append(i)
print (result)
#方法2:
result = []
s="abbaaba"
index =0
while 1:
position = s.find("ab",index)
if position != -1:
result.append(position)
index =position+1
else:
break
print (result)
1.8.6. '''判断一句话中有几个数字和几个空白,几个字母
和其他字符有几个'''
num_count=0
str_count=0
space_count=0
other_count=0
s="I am a 12 years old boy! hi,me!"
for i in s:
if i.isdigit():
num_count+=1
elif i.isalpha():
str_count+=1
elif i.isspace():
space_count+=1
else:
other_count+=1
print(num_count,str_count,space_count,other_count)
1.8.7. '''实现自己的join/find/index/count/findall方法'''
class huang_str(object):
@classmethod
def join(cls,arr,s):
result =""
for i in arr:
result += str(i) +s
return result.rstrip(s)
@classmethod
def find(cls,arr,targtet_str,start_position=0,end_position=None):
if not isinstance(start_position,int):
return -1
if end_position==None:
end_position=len(arr)
for i in range(start_position,end_position):
if arr[i:i+len(targtet_str)] == targtet_str:
return i
return -1
@classmethod
def index(cls,arr,targtet_str,start_position=0,end_position=None):
if not isinstance(start_position,int):
return -1
if end_position==None:
end_position=len(arr)
for i in range(start_position,end_position):
if arr[i:i+len(targtet_str)] == targtet_str:
return i
raise ValueError('substring not found')
@classmethod
def count(cls,arr,targtet_str,start_position=0,end_position=None):
num=0
if not isinstance(start_position,int):
return -1
if end_position==None:
end_position=len(arr)
for i in range(start_position,end_position):
if arr[i:i+len(targtet_str)] == targtet_str:
num+=1
return num
@classmethod
def count(cls,s,target_str,start_position=0,end_position=None):
index = start_position
if end_position is None:
end_position = len(s)
times = 0
while index < end_position-1:
if s[index:index+len(target_str)] == target_str:
times+=1
index += len(target_str)
else:
index+=1
return times
@classmethod
def findall (cls,arr,targtet_str,start_position=0,end_position=None):
result = []
if end_position==None:
end_position=len(arr)
temp = arr[start_position:end_position]
for i in range(len(temp)):
if temp[i:i+len(targtet_str)] == targtet_str:
result.append( i+start_position)
return result