05 - 字符串


一.字符串的表示方式

  • 雙引號或者單引號中的數據,就是字符串
  • 如果使用一對引號來定義字符串,當出現符號沖突時可以使用轉義字符
  • 使用三個單引號、雙引號定義的字符串可以包裹任意文本

二.字符串的賦值和地址問題

  • s1、s2、s3的地址相同 / s4的地址不同
s1 = 'hello'
s2 = s1           #s1將地址賦給s2,這樣s1和s2指向的是常量池中同一個字符串
s3 = "hello"      #hello這個字符串在常量池中已經存在,所以將地址給s3,那么s3和s1、s2地址相同
s4 = 'hello1'     #常量池中沒有hello1這個字符串,會在常量池中新開辟一個地址,賦給s4

id(變量):id()函數用於將變量的內存地址得到轉化為我們能看懂的地址

變量a is 變量b:is用於比較地址是否相同

  • 當沒有任何指針指向字符串,字符串就會被回收

三.字符串的索引機制

  • 正向取索引(str = 'abcde')

    0 ~ len(str)-1

    從左到右索引依次為:0 1 2 3 4

  • 反向取索引

    -len(str) ~ -1

    從右往左索引依次為:-1 -2 -3 -4 -5

    有時候字符串長度很長,如果正向去取會很麻煩,但是如果倒着取,那么倒數第一個字符下標就為-1,向左依次為-2、-3、-4...

四.字符串相關操作

1.獲取字符串長度

  • len(字符串)

2.截取指定字符串

  • 依據字符串索引機制,按索引取

    str = 'abcdef'
    print(str[1])   #b
    print(str[-2])  #e
    

3.截取多個字符串(切片)

  • 切片用於字符串和列表

  • 格式:字符串變量[start:end:step]

    1. 步長省略
    • [start:end] #左閉右開

      • 正向索引

        str = 'abcde'
        print(str[1:3])      #bc
        
      • 反向索引

        str = 'abcde'
        print(str[-4:-2])    #bc  也是左閉右開
        
      • 正反索引可以混用

        str = 'abcde'
        print(str[1:-2])    #bc
        
    • [:end] #默認從0開始

      str = 'abcde'
      print(str[:3])    #abc
      print(str[:-1])   #abcd
      
    • [start:] #從start開始取到最后

      str = 'abcde'
      print(str[2:])    #cde
      print(str[-2:])   #de
      
    • [:] #從頭取到尾

      str = 'abcde'
      print(str[:])     #abcde
      

      注意:此時用切片的方式取出全部字符串和原字符串地址一樣


    • list1[1:1] = [2,3] #比較特殊,根據底層原碼大致理解為先看等號后面的列表長度n,然后再1:切片的位置之后含切片位置的所有元素后移n位,然后將等號后面的列表中的元素依次插入

      list1 = [1,4]
      list1[1:1] = [2,3,{1,2},(1,2),{'a':1},'str']
      print(list1)  #[1, 2, 3, {1, 2}, (1, 2), {'a': 1}, 'str', 4]
      

      注意只有列表的切片才能這樣使用!!

    1. 加上步長
    • [start : end : step]

      str = 'abcdef'
      print(str[1:-1:2])   #bdf
      
    • [ : end : step]

      str = 'abcdef'
      print(str[:-1:3])   #ad    
      
    • [start : : step]

      str = 'abcdef'
      print(str[2::2])    #ce  
      
    • [ : : step]

      str = 'abcdef'
      print(str[::-1])    #fedcba
      print(str[::-2])    #fdb
      
    • [ : : : ]

      str = 'abcdef'
      print(str[::])    #abcdef
      

    注意:步長如果為正表示從左到右取,如果步長為負數表示從右往左反着取

    而且一定注意:當步長為負數時,說明從右往左反着取,那么start的索引值一定要在end索引值的后面!!

  • 易錯舉例:

    str = 'abcdef'
    print(str[1:-1:-2])    #這樣會取不到任何值!!!!因為step為-2表示倒着取,起始索引為1,倒着取下一個為                         0,這樣就永遠到不了-1索引,所以取不到任何值
    print(str[-1:1:-2])    #這樣就可以取到值--fd  (還是左閉右開)
    print(str[5::-1])      #從索引為5開始往前取--fedcba
    

4.查找(獲取指定字符下標)

  • find:從左向右查找,只要遇到一個符合要求的則返回位置值。如果沒有找到任何符合要求的則返回-1

    path = 'https://www.baidu.com/img/dong_e39494cd9293c9d9cc9d0gk303945.gif'
    i = path.find('_')                
    print(path[i+1:])                 #取_后面的字符串
    
    mystr = '今天天氣好晴朗,處處好風光呀好風光'
    print(mystr.find('好風光'))        #10   '好風光'第一次出現時,'好'所在的位置
    print(mystr.find('風光',1,10))     #-1 從下標1開始到12查找"風光",未找到,返回 -1
    
  • rfind:類似於 find()函數,不過是從右邊開始查找。如果沒有找到任何符合要求的則返回-1

    mystr = '今天天氣好晴朗,處處好風光呀好風光'
    print(mystr.rfind('好'))           #14
    
  • index:跟find()方法一樣,只不過,find方法未找到時,返回-1,而str未找到時,會報一個異常

  • rindex:類似於 index(),不過是從右邊開始。

5.判斷

  • startswith:判斷字符串是否以指定內容開始。

    mystr = '今天天氣好晴朗,處處好風光呀好風光'
    print(mystr.startswith('今'))  # True
    
  • endswith:判斷字符串是否以指定內容結束。

    mystr = '今天天氣好晴朗,處處好風光呀好風光'
    print(mystr.endswith('好風光')) #True
    
  • isalpha:判斷字符串是否是純字母

    mystr = 'hello world'
    print(mystr.isalpha()) # False 因為中間有空格
    
  • isdigit:判斷一個字符串是否是純數字,只要出現非0~9的數字,結果就是False.

  • isalnum:判斷是否由數字和字母組成。只要出現了非數字和字母,就返回False.

  • isspace:如果 mystr 中只包含空格,則返回 True,否則返回 False.

  • isupper:判斷是否全部是大寫字母

  • islower:判斷是否全部是小寫字母

6.統計出現次數

  • count:返回 str在start和end之間 在 mystr里面出現的次數。

    mystr = '今天天氣好晴朗,處處好風光呀好風光'
    print(mystr.count('好'))      #3    '好'字出現三次
    

7.替換

  • replace:替換字符串中指定的內容。如果沒有指定次數則全部替換;如果指定次數count,則替換不會超過count次。
mystr = '今天天氣好晴朗,處處好風光呀好風光'
newstr = mystr.replace('好', '壞')
print(mystr)  # 今天天氣好晴朗,處處好風光呀好風光  原字符串未改變!
print(newstr)  # 今天天氣壞晴朗,處處壞風光呀壞風光 得到的新字符串里,'好'被修改成了'壞'

newstr = mystr.replace('好','壞',2)  # 指定了替換的次數
print(newstr) # 今天天氣壞晴朗,處處壞風光呀好風光 只有兩處的'好'被替換成了'壞'

注意:替換完的新字符串不會覆蓋原字符串

  • 疑問:如果要替換多個怎么辦-------1.正則表達式 2.列表加循環 (后面會詳解)

8.切割(分割字符串)

  • split:以指定字符串為分隔符切片,如果 maxsplit有指定值,則僅分隔 maxsplit+1 個子字符串。返回的結果是一個列表。
mystr = '今天天氣好晴朗,處處好風光呀好風光'
result = mystr.split() # 沒有指定分隔符,默認使用空格,換行等空白字符進行分隔
print(result) #['今天天氣好晴朗,處處好風光呀好風光'] 沒有空白字符,所以,字符串未被分隔

result = mystr.split('好')  # 以 '好' 為分隔符
print(result) # ['今天天氣', '晴朗,處處','風光呀,'風光']

result = mystr.split("好",2) # 以 '好' 為分隔符,最多切割成3份
print(result) # ['今天天氣', '晴朗,處處', '風光呀好風光']
  • rsplit:用法和split基本一致,只不過是從右往左分隔。
  • splitlines(了解):按照行分隔,返回一個包含各行作為元素的列表。
mystr = 'hello \nworld'
mystr = '''第一行
第二行
第三行
'''
print(mystr.splitlines())
  • partition(了解):把mystr以指定str分割成三部分,str前,str和str后,三部分組成一個元組
mystr = '今天天氣好晴朗,處處好風光呀好風光'
print(mystr.partition('好'))  # ('今天天氣', '好', '晴朗,處處好風光呀好風光')
  • rpartition(了解):類似於 partition()函數,不過是從右邊開始.

9.大小寫轉化

  • title:每個單詞的首字母大寫。
mystr = 'hello world'
print(mystr.title()) # Hello World
  • capitalize:第一個單詞的首字母大寫。
  • upper:所有都變成大寫。
  • lower:所有都變成小寫。

10.空格處理

  • strip:刪除兩端的空白字符

    str = '    he   llo      '
    print(str.strip())  #he   llo
    
  • lstrip:刪除 mystr 左邊的空白字符

  • rstrip:刪除 mystr 右邊的空白字符

  • ljust:返回指定長度的字符串,並在右側使用空白字符補全(左對齊)。

  • rjust:返回指定長度的字符串,並在左側使用空白字符補全(右對齊)。

  • center:返回指定長度的字符串,並在兩端使用空白字符補全(居中對齊)

    str = 'hello'
    print(str.center(10))  #  hello   兩端加空格,讓內容居中
    

11.字符串拼接

  • join:把參數進行遍歷,取出參數里的每一項,然后再在后面加上mystr

    一般用於列表--->返回一個字符串

    mystr = 'a'
    print(mystr.join('hxmdq'))  #haxamadaq  把hxmd一個個取出,並在后面添加字符a. 最后的q保留,沒有加a
    print(mystr.join(['hi','hello','good']))  #hiahelloagood
    
  • +號:正常拼接字符串

12.字符串format格式化

  • 概念

    str.format() 方法通過字符串中的大括號{} 來識別替換字段 replacement field,從而完成字符串的格式化。

  • 字段名的種類

    • 1.省略字段名:{}

      注意:大括號個數可以少於位置參數的個數,反之不然

      name = '小明'
      age = 18
      print('我叫{},今年{}歲。'.format(name, age))
      
      # 大括號個數可以少於位置參數的個數
      print('我愛吃{}和{}。'.format('香蕉', '蘋果', '大鴨梨'))
      
      # 大括號個數多於位置參數的個數則會報錯
      # print('我還吃{}和{}。'.format('西紅柿'))
      """
      IndexError: tuple index out of range
      """
      
    • 2.使用非負十進制整數{0}

      • 數字必須是大於等於 0 的整數。

      • 帶數字的替換字段可以重復使用

        # 數字形式的簡單字段名可以重復使用。
        name = '阿香'
        age = 17
        print('我愛{0}。\n她今年{1}。\n我也愛{0}。'.format(name, age))
        """
        我愛阿香。
        她今年17。
        我也愛阿香。
        """
        
      • 數字形式的簡單字段名相當於把 format 中的所有位置參數整體當作一個元組,通過字段名中的數字進行取值。即 {0} 等價於 tuple[0],所以大括號內的數字不能越界。

        # 體會把所有位置參數整體當成元組來取值
        print('阿香愛吃{1}、{3}和{0}。'.format(
            '榴蓮', '臭豆腐', '皮蛋', '鯡魚罐頭', '螺獅粉'))
        """
        阿香愛吃臭豆腐、鯡魚罐頭和榴蓮。
        """
        
    • 3.變量名{name}

      • 使用變量名形式的簡單字段名傳遞關鍵字參數

      • 使用變量名關鍵字參數的位置可以隨意調換。

      • 但是注意:變量名做參數時一定要在format中賦值

      # 關鍵字參數的順序可以隨意調換
      print('我大哥是{name},今年{age}歲。'.format(age=20, name='阿飛'))
      """
      我大哥是阿飛,今年20歲。
      """
      
    • 4.簡單字段名的混用

      • 混合使用數字形式和變量名形式的字段名,可以同時傳遞位置參數和關鍵字參數。

      • 關鍵字參數必須位於位置參數之后。

        # 關鍵字參數必須位於位置參數之后
        print('這是一個關於{0}、{1}和{girl}的故事。'.format(
            '小明', '阿飛', girl='阿香'))
        """
        這是一個關於小明、阿飛和阿香的故事。
        """
        
      • 混合使用時可以省略數字。

        # 數字也可以省略
        print('這是一個關於{}、{}和{girl}的故事。'.format(
            '小明', '阿飛', girl='阿香'))
        
      • 省略字段名 {} 不能和數字形式的字段名 {非負整數} 同時使用。

        # 但是省略字段名不能和數字形式的字段名同時出現
        # print('這是一個關於{}、{1}和{girl}的故事。'.format(
        #     '小明', '阿飛', girl='阿香'))
        """
        ValueError: cannot switch from automatic field numbering to manual field specification
        """
        

例題1:利用切片和字符串方法

  • 模擬上傳文件,鍵盤輸入上傳文件的名稱(不帶后綴名),判斷文件名是否大於6位以上,拓展名是否是:jpg、gif、png格式,如果不是則提示上傳失敗,如果名字不滿足條件,而拓展名滿足條件則隨機生成一個6位數字組成的文件名,打印成功上傳xxx.png等
import random
document = input('請輸入上傳文件名稱:')
index = document.rfind('.')
if document.endswith('.jpg') or document.endswith('.gif') or document.endswith('.png'):
    if len(document[index - 1::-1]) >= 6:  #或者寫[:index]
        print('打印成功上傳%s' % document)
    else:
        newName = random.randint(100000,999999)   #randint()是左閉右閉的
        print('打印成功上傳%d%s' % (newName,document[index:]))
else:
    print('格式不滿足上傳失敗')   1748

改進:

  • 隨機生成一個由字母和數字組成的6位文件名 (很牛的方法--驗證碼就是這么來的)
filename = ''   #表示filename是空的字符串類型的變量
s = 'abcdefghigklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'  #所有可能的情況
for i in range(6):
    index = random.randint(0,len(s) - 1)   #隨機取一個整數,去表示s中的索引
    filename += s[index]     #將從s字符串中取出的元素拼接成6位字符串
print(filename)

例題2:字符串判斷

'''
admin123 19182134110 123456
用戶名或者手機號登錄+密碼

用戶名:全部小寫,首字母不能是數字,長度必須6位以上
手機號碼:純數字、長度11
密碼必須是6位數字

以上符合條件則進入下層驗證:
判斷用戶名+密碼 是否正確,成功或失敗
'''
flag = True
error = 0
while flag:
    if error < 3:
        name = input('請輸入用戶名或手機號:')
        if (name.islower() and not name[0].isdigit() and len(name) > 6) or (name.isdigit() and len(name) == 11):
            while error < 3:
                password = input('請繼續輸入密碼:')
                if password.isdigit() and len(password) == 6:
                    if (name == '19182134110' or name == 'admin123') and  password == '123456':
                        print('登錄成功!')
                        flag = False
                        break
                    else:
                        print('賬號或密碼錯誤!(還有%d次嘗試機會)' % (2 - error))
                        error += 1
                        break
                else:
                    print('密碼必須是6位!(還有%d次嘗試機會)' % (2 - error))
                    error += 1
                    break
        else:
            print('用戶名或手機輸入格式錯誤')
    else:
        print('賬號鎖定!')
        flag = False


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM