字符串

字符串笔记整理

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则返回 -1start和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

posted on 2018-09-17 16:56  淡淡的风景  阅读(215)  评论(0编辑  收藏  举报