第5章 字串及正則表示式
第5章 字串及正則表示式
5.1 字串常用操作
在Python開發過程中,為了實現某項功能,經常需要對某些字串進行特殊處理,如拼接字串、擷取字串、格式化字串等。下面將對Python中常用的字串操作方法進行介紹。
5.1.1 拼接字串
使用“+” 運算子可完成對多個字串的拼接,“+” 運算子可以連線多個字串併產生一個字串物件。
例如,定義兩個字串,一個儲存英文版的名言,另一個用於儲存中文版的名言,然後使用“+” 運算子連線,程式碼如下:
mot_en = 'Remembrance is a form of meeting. Forgetfulness is a form of freedom.' mot_cn = '記憶是一種相遇。遺忘是一種自由。' print(mot_en + '——' + mot_cn)
上面的程式碼執行後,將顯示以下內容:
Remembrance is a form of meeting. Forgetfulness is a form of freedom.——記憶是一種相遇。遺忘是一種自由。
字串不允許直接與其他型別的資料拼接,例如,使用下面的程式碼將字串與數值拼接在一起,將產生如下異常。
str1 = '我今天一共走了'# 定義字串 num = 2456# 定義一個整數 str2 = '步'# 定義字串 print(str1 + num + str2)# 對字串和整數進行拼接
Traceback (most recent call last): File "D:\python3.6.5\練習檔案\demo.py", line 532, in <module> print(str1 + num + str2)# 對字串和整數進行拼接 TypeError: must be str, not int >>>
解決該問題,可以將整數轉換為字串,然後以拼接字串的方法輸出該內容。將整數轉換為字串,可以使用str() 函式,修改後的程式碼如下:
str1 = '我今天一共走了'# 定義字串 num = 2456# 定義一個整數 str2 = '步'# 定義字串 print(str1 + str(num) + str2)# 對字串和整數進行拼接
上面程式碼執行後,將顯示以下內容:
我今天一共走了2456步
場景模擬:一天,兩名程式設計師坐在一起聊天,於是產生了下面的笑話:程式設計師甲認為程式開發枯燥而辛苦,想換行,詢問程式設計師乙該怎麼辦。而程式設計師乙讓其敲一下回車鍵。試著用程式輸出這一笑話。
例項01:使用字串拼接輸出一個關於程式設計師的笑話
建立一個檔案,在該檔案中定義兩個字串變數,分別記錄兩面程式設計師說的話,再將兩個字串拼接到一起,並且在中間拼接一個轉義字串(換行符),最後輸出,程式碼如下:
programmer_1 = '程式設計師甲:搞IT太辛苦了,我想換行……怎麼辦?' programmer_2 = '程式設計師乙:敲一下回車鍵' print(programmer_1 + '\n' + programmer_2)
執行結果如下:
程式設計師甲:搞IT太辛苦了,我想換行……怎麼辦? 程式設計師乙:敲一下回車鍵
5.1.2 計算字串的長度
由於不同的字元所佔位元組數不用,所以要計算字串的長度,需要先了解各字元所佔的位元組數。在Python 中,數字、英語、小數點、下劃線和空格佔一個位元組;一個漢字可能會佔2~4個位元組,佔幾個位元組
取決於採用的編碼。漢字在GBK/GB2312 編碼中佔2 個位元組,在UTF-8/unicode 編碼中一般佔用3 個位元組(或4 個位元組)。下面以Python 預設的UTF-8 編碼為例進行說明,即一個漢字佔3 個位元組。
在Python 中,提供了len() 函式計算字串的長度,語法格式如下:
len(string)
其中,string 用於指定要進行長度統計的字串。例如,定義一個字串,內容為“人生苦短,我用Python!”,然後應用len() 函式計算該字串的長度,程式碼如下:
str1 = '人生苦短,我用Python!'# 定義字串 length = len(str1)# 計算字串的長度 print(length)
上面的程式碼在執行後,將輸出結果‘14’。
從上面的結果中可以看出,在預設的情況下,通過len() 函式計算字串的長度,不區分英文,數字和漢字,所有字元都按一個字元計算。
在實際開發時,有時需要獲取字串實際所佔的位元組數,即如果採用UTF-8 編碼,漢字佔3 個位元組,採用GBK 或者GB2312 時,漢字佔2 個位元組。這時,可以通過使用encode() 方法(參加5.2.1 小節)進行編碼後再進行獲取。例如,如果獲取採用UTF-8 編碼的字串的長度,可以使用下面的程式碼:
str1 = '人生苦短,我用Python!'# 定義字串 length = len(str1.encode ())# 計算UTF-8編碼的字串的長度 print(length)
……
如果要獲取採用GBK 編碼的字串的長度,可以使用下面的程式碼。
str1 = '人生苦短,我用Python!'# 定義字串 length = len(str1.encode ('gbk'))# 計算UTF-8編碼的字串的長度 print(length)
5.1.3 擷取字串
由於字串也屬於序列,所以要擷取字串,可以採用切片方法實現。通過切片方法擷取字串的語法格式如下:
string[start:end:step]
引數說明:
- string:表示要擷取的字串。
- start:表示要擷取的第一個字元的索引(包括該字元),如果不指定,則預設為0。
- end:表示要擷取的最後一個字元的索引(不包括該字元),如果不指定則預設字串的長度。
- step:表示切片的步長,如果省略,則預設為1,當省略該步長時,最後一個冒號也可以省略。
說明:字串的索引同序列的索引是一樣的,也是從0 開始,並且每個字元佔一個位置。
例如,定義一個字串,然後應用切片方法擷取不同長度的字串,並輸出,程式碼如下:
str1 = '人生苦短,我用Python!'# 定義字串 substr1 = str1[1]# 擷取第2個字元 substr2 = str1[5:]# 從第6個字元擷取 substr3 = str1[:5]# 從左邊開始擷取第5個字元 substr4 = str1[2:5]# 擷取第3個到第5個字元 print('原字串:',str1) print(substr1 + '\n' + substr2 + '\n' + substr3 + '\n' + substr4)
上面的程式碼執行後,將顯示以下內容:
原字串: 人生苦短,我用Python! 生 我用Python! 人生苦短, 苦短,
……
例項02:擷取身份證號碼的出生日期
……截取出初設是哪個日期,並組合成YYYY年MM月DD日“”格式的字串,最後輸出擷取到的出生日期和生日,程式碼如下:
programer_1 = '你知道我的生日嗎?'# 程式設計師甲問程式設計師乙的臺詞 print('程式設計師甲說:',programer_1)# 輸出程式設計師甲的臺詞 programer_2 = '輸入你的身份證號碼。'# 程式設計師乙的臺詞 print('程式設計師乙說:',programer_2)# 輸出程式設計師乙的臺詞 idcard = '101252198501058866'# 定義儲存身份證號碼的字串 print('程式設計師甲說:',idcard)# 程式設計師甲說出身份證號碼 birthday = idcard[6:10] + '年' + idcard[10:12] + '月' + idcard[12:14] + '日'# 擷取生日 print('程式設計師乙說:','你是' + birthday + '出生的,所以你的生日是' + birthday[5:])
執行結果如下:
程式設計師甲說: 你知道我的生日嗎? 程式設計師乙說: 輸入你的身份證號碼。 程式設計師甲說: 101252198501058866 程式設計師乙說: 你是1985年01月05日出生的,所以你的生日是01月05日
5.1.4 分割、合併字串
在Python 中,字串物件提供了分割和合並字串的方法。分割字串是把字串分割為列表,而合併字串是把列表合併為字串,分割字串和合並字串可以看作是互逆操作。
1. 分割字串
字串物件的split() 方法可以實現字串分割,也就是把一個字串按照指定的分隔符切分為字串列表。該列表的元素中,不包括分隔符。split() 方法的語法格式如下:
str.split(sep,maxsplit)
引數說明:
- str:表示要進行分割的字串。
- sep:用於指定分隔符,可以包含多個字元,預設為None,即所有空字元(包括空格、換行“\n”、製表符“\t”等)。
- maxsplit:可選引數,用於指定分割的次數,如果不指定或者為-1,則分割次數沒有限制,否則返回結果列表的元素個數,個數最多為maxsplit+1。
- 返回值:分隔後的字串列表。
說明:在split() 方法中,如果不指定sep 引數,那麼也不能指定maxsplit 引數。
例如,定義一個儲存部落格園網站的字串,然後應用split() 方法根據不同的分隔符進行分割,程式碼如下:
str1 = '博 客 園 官 網 >>> www.cnblogs.com/' print('原字串:',str1) list1 = str1.split()# 採用預設分隔符進行分割 list2 = str1.split('>>>')# 採用多個字元進行分割 list3 = str1.split('.')# 採用.號進行分割 list4 = str1.split(' ',4)# 採用空格進行分割,並且只分割前4個 print(str(list1) + '\n' + str(list2) + '\n' + str(list3) + '\n' + str(list4)) list5 = str1.split('>')# 採用>進行分割 print(list5)
上面的程式碼在執行後,將顯示以下內容:
原字串: 博 客 園 官 網 >>> www.cnblogs.com/ ['博', '客', '園', '官', '網', '>>>', 'www.cnblogs.com/'] ['博 客園 官 網 ', ' www.cnblogs.com/'] ['博 客園 官 網 >>> www', 'cnblogs', 'com/'] ['博', '客', '', '園', '官 網 >>> www.cnblogs.com/'] ['博 客園 官 網 ', '', '', ' www.cnblogs.com/']
說明:在使用split() 方法時,如果不指定引數,預設採用空白符進行分割,這是無論有幾個空格或者空白符都將作為一個分隔符進行分割。……
場景模擬:微博的@好友欄目中,輸入“@馬雲 @雷軍 @馬化騰”(好友之間用一個空格區分),同時@三個好友。
例項03:輸出被@三個好友。
在IDLE中建立一個名稱為atfriend.py 的檔案,然後在該檔案中定義一個字串,內容為“@馬雲 @雷軍 @馬化騰”,然後使用split() 方法對該字串進行分割,從而取出好友名稱,並輸出,程式碼如下:
str1 ='@馬雲 @雷軍 @馬化騰' list1 = str1.split(' ')# 用空格分隔字串 print('您@的好友有:') for item in list1: print(item[1:])# 輸出每個好友名字時,去掉@符號
執行結果如下:
您@的好友有: 馬雲 雷軍 馬化騰
2. 合併字串
合併字串與拼接字串不同,它會將多個字串採用固定的分隔符連線在一起。例如,字串“灰灰*木馬*小麗*萊德”,就可以看做是通過分隔符“ * ” 將['灰灰';'木馬','小麗'',萊德']列表合併為一個字串的結果。
合併字串可以使用字串物件的join() 方法實現,語法格式如下:
strnew = string.join(iterable)
引數說明:
- strnew:表示合成後生成新的字串。
- string:字串型別,用於指定合併時的分隔符。
- iterable:可迭代物件,該迭代物件中的所有元素(字串表示)將被合併為一個新的字串。string 作為邊界點分割出來。
場景模擬:微博的@好友欄目中,輸入“@馬雲 @雷軍 @馬化騰”(好友之間用一個空格區分),即可同時@三個好友。現在想要@好友列表中的全部好友,所以需要組合一個類似的字串。
例項04:通過好友列表生成全部被@的好友
在IDLE 中建立一個名稱為atfriend-join.py 的檔案,然後在該檔案中定義一個列表,儲存一些好友名稱,然後使用 join() 方法將列表中每個元素用空格 +@ 符號進行連線,再在連線後的字串前新增一個 @ 符號,最後輸出,程式碼如下:
list_friend =['馬雲','雷軍','馬化騰','王永林','牛根生']# 好友列表 str_friend = ' @'.join (list_friend)# 用空格+@符號進行連線 at = '@'+str_friend#由於使用join() 方法時,第一個元素前不加分隔符,所以需要在前面加上@符號 print('您要@的好友:',at)# 輸出每個好友名字時,去掉@符號
執行結果如下:
您要@的好友: @馬雲 @雷軍 @馬化騰 @王永林 @牛根生
5.1.5 檢索字串
在Python中,字串物件提供了很多應用於字串查詢的方法,這裡介紹以下幾種方法,這裡主要介紹以下幾種方法。
1. count() 方法
count() 方法用於檢索指定字串在另一個字串中出現的次數。如果檢索的字串不存在,則返回0,否則返回出現的次數。其語法格式如下:
str.count(sub[, start[, end]])
引數說明:
- str:表示原字串。
- sub:表示要檢索的子字串。
- start:可選引數,表示檢索範圍的起始位置的索引,如果不指定,則從頭開始檢索。
- end:可選引數,表示檢索範圍的結束位置的索引,如果不指定,則一直檢索到結尾。
例如,定義一個字串,然後應用count() 方法檢索該字串“@”符號出現的次數,程式碼如下:
str1 ='@馬雲 @雷軍 @馬化騰' print('字串“',str1,'”中包括',str1.count('@'),'個@符號')
上面的程式碼執行後,將顯示以下結果:
字串“ @馬雲 @雷軍 @馬化騰 ”中包括 3 個@符號
2. find() 方法
該方法用於檢索是否包含指定的子字串。如果檢索的字串不存在,則返回-1,否則返回首次出現該子字串時的索引。其語法格式如下:
str.find(sub[, start[, end]])
引數說明:
- str:表示原字串。
- sub:表示要檢索的子字串。
- start:可選引數,表示檢索範圍的起始位置的索引,如果不指定,則從頭開始檢索。
- end:可選引數,表示檢索範圍的結束位置的索引,如果不指定,則一直檢索到結尾。
例如,定義一個字串,然後應用find() 方法檢索該字串中首次出現“@”符號的位置索引,程式碼如下:
str1 ='@馬雲 @雷軍 @馬化騰' print('字串“',str1,'”中@符號首次出現的位置索引為:',str1.find('@'))
上面的程式碼執行後,將顯示以下結果:
字串“ @馬雲 @雷軍 @馬化騰 ”中@符號首次出現的位置索引為: 0
說明:如果只是想要判斷指定的字串是否存在,可以使用in 關鍵字實現。例如,上面的字串str1 中是否存在@符號,可以使用print(‘@’in str1) ,如果存在就返回True,否則返回False。另外,也可以根據find() 方法的返回值是否大於-1來確定的字串是否存在。
如果輸入的子字串在原字串中不存在,將返回-1。例如下面的程式碼:
str1 ='@馬雲 @雷軍 @馬化騰' print('字串“',str1,'”中*符號首次出現的位置索引為:',str1.find('*'))
上面的程式碼執行後,將顯示以下結果:
字串“ @馬雲 @雷軍 @馬化騰 ”中*符號首次出現的位置索引為: -1
說明:Python的字串物件還提供了rfind() 方法,其作用於find() 方法類似,只是從字串右邊開始查詢。
3. index() 方法
index() 方法同find() 方法類似,也是用於檢索是否包含指定的子字串。只不過如果使用index() 方法,當指定的字串不存在時會丟擲異常。其語法格式如下:
str.index(sub[, star[, end]])
引數說明:
- str:表示原字串。
- sub:表示要檢索的子字串。
- start:可選引數,表示檢索範圍的起始位置的索引,如果不指定,則從頭開始檢索。
- end:可選引數,表示檢索範圍的結束位置的索引,如果不指定,則一直檢索到結尾。
- 例如,定義一個字串,然後應用index() 方法檢索該字串中首次出現“@”符號的位置索引,程式碼如下:
str1 ='@馬雲 @雷軍 @馬化騰' print('字串“',str1,'”中@符號首次出現的位置索引為:',str1.index('@'))
上面的程式碼執行後,將顯示以下結果:
字串“ @馬雲 @雷軍 @馬化騰 ”中@符號首次出現的位置索引為: 0
如果輸入的子字串在原字串中不存在,將會產生異常,例如下面的程式碼:
str1 ='@馬雲 @雷軍 @馬化騰' print('字串“',str1,'”中*符號首次出現的位置索引為:',str1.index('*'))
上面的程式碼執行後,將顯示如下異常:
Traceback (most recent call last): File "D:\python3.6.5\練習檔案\demo.py", line 621, in <module> print('字串“',str1,'”中*符號首次出現的位置索引為:',str1.index('*')) ValueError: substring not found
說明:Python的字串物件還提供了rindex() 方法,其作用於index() 方法類似,只是從右邊開始查詢。
4. startswith() 方法
starswith() 方法用於檢索字串是否以指定子字串開頭。如果是則返回True,否則返回False。該方法語法格式如下:
str.startswith(prefix[, start[, end]])
引數說明:
- str:表示原字串。
- prefix:表示要檢索的子字串。
- start:可選引數,表示檢索範圍的起始位置的索引,如果不指定,則從頭開始檢索。
- end:可選引數,表示檢索範圍的結束位置的索引,如果不指定,則一直檢索到結尾。
- 例如,定義一個字串,然後應用startswith() 方法檢索該字串中首次出現“@”符號的位置索引,程式碼如下:
str1 ='@馬雲 @雷軍 @馬化騰' print('字串“',str1,'”是否以@符號開頭,結果為:',str1.startswith('@'))
上面的程式碼執行後,將顯示以下結果:
字串“ @馬雲 @雷軍 @馬化騰 ”是否以@符號開頭,結果為: True
5. endswinth() 方法
endswinth() 方法用於檢索字串是否以指定的子字串結尾。如果是則返回True,否則返回False。該方法語法格式如下:
str.endswith(suffix[, start[, end]])
引數說明:
- str:表示原字串。
- suffix:表示要檢索的子字串。
- start:可選引數,表示檢索範圍的起始位置的索引,如果不指定,則從頭開始檢索。
- end:可選引數,表示檢索範圍的結束位置的索引,如果不指定,則一直檢索到結尾。
- 例如,定義一個字串,然後應用endswith() 方法檢索該字串是否以“.com”結尾,程式碼如下:
str1 ='https://www.cnblogs.com' print('字串“',str1,'”是否以.com結尾,結果為:',str1.endswith('.com'))
上面的程式碼執行後,將顯示以下結果:
字串“ https://www.cnblogs.com ”是否以.com結尾,結果為: True
5.1.6 字母的大小寫轉換
在Python中,字串物件提供了lower() 方法和upper() 方法進行字母的大小寫轉換,即可用於將大寫字元轉換為小寫字母或者將小寫字母轉換為大寫字母。
1.lower() 方法
lower() 方法用於將字串中的大寫字母轉換為小寫字母。如果字串中沒有需要被轉換的字元,則將原字串返回;否則將返回一個新的字串,將原字串中每個需要進行小寫轉換的字元都轉換成等價的小寫字元。字元長度與元字元長度相同。lower() 方法的語法格式如下:
str.lower()
其中,str 為要進行轉換的字串。
例如,使用lower() 方法後,下面定義的字串將全部顯示為小寫字母。
str1 ='https://WWW.cnblogs.Com' print('字串',str1) print('新字串',str1.lower())# 全部轉換為小寫字母輸出
2. upper() 方法
upper() 方法用於將字串中的小寫字母轉換為大寫字母。……
str.upper()
str1 ='https://www.cnblogs.com' print('字串',str1) print('新字串',str1.upper())# 全部轉換為大寫字母輸出
例項05:不區分大小寫驗證會員名是否唯一
程式碼如下:
# 假設已經註冊的會員名稱儲存在一個字串中,以“|”進行分割 username_1 = '|LiaoXi|liaoxi|sy|SHENYANG|' username_2 = username_1.lower()# 將會員名稱字串全部轉換為小寫 regname_1 = input('輸入要註冊的會員名稱:') regname_2 = '|' + regname_1.lower() + '|'# 將要註冊的會員名稱全部轉換為小寫 if regname_2 in username_2:# 判斷輸入的會員名稱是否存在 print('會員名',regname_1,'已經存在!') else: print('會員名',regname_1,'可以註冊了!')
5.1.7 去除字串中的空格和特殊字元
使用者在輸入資料時,可能會無意中輸入多餘的空格,或在一些情況下,字串前後不允許出現空格和特殊字元,此時就需要去除字串中的空格和特殊字元。……
說明:這裡的特殊字元是指製表符\t、回車符\r、換行符\n等。
1. strip() 方法
strip() 方法用於去掉字串左、右兩側的空格和特殊字元,語法格式如下:
str.strip([chars])
引數說明 :
- str:為要去除空格的字串。
- chars:為可選引數,用於指定要去除的字元,可以指定多個。如果設定chars 為“@.”,則去除左、右兩側包括的“@” 或“.”。如果不指定chars 引數,預設將去除空格、製表符“\t”、回車符“\r”、換行符“\n”等。
例如,先定義一個字串,首尾包括空格、製表符、換行符和回車符等,然後去除空格和這些特殊字元;再定義一個字串,首尾包括“@” 或“.” 字元,最後去掉“@” 或“.”,程式碼如下:
str1 = 'https://www.cnblogs.com\t\n\r' print('原字串str1:' + str1 + '。') print('字串',str1.strip() + '。')# 去除字串首尾的空格和特殊字元 str2 = '@部落格園.@.' print('原字串str1:' + str2 + '。') print('字串',str2.strip('@.') + '。')# 去除字串首尾的空格和特殊字元
執行結果如下:
原字串str1:https://www.cnblogs.com 。 字串 https://www.cnblogs.com。 原字串str1:@部落格園.@.。 字串 部落格園。
2. Istrip() 方法
lstrip() 方法用於去掉字串左側的空格和特殊字元,語法格式如下:
str.lstrip([chars])
引數說明:
- str:為要去除空格的字串。
- chars:為可選引數,用於指定要去除的字元,可以指定多個。如果設定chars 為“@.”,則去除左、右兩側包括的“@” 或“.”。如果不指定chars 引數,預設將去除空格、製表符“\t”、回車符“\r”、換行符“\n”等。
……
3. rstrip() 方法
rstrip() 方法用於去掉字串左側的空格和特殊字元,語法格式如下:
str.rstrip([chars])
引數說明:
- str:為要去除空格的字串。
- chars:為可選引數,用於指定要去除的字元,可以指定多個。如果設定chars 為“@.”,則去除左、右兩側包括的“@” 或“.”。如果不指定chars 引數,預設將去除空格、製表符“\t”、回車符“\r”、換行符“\n”等。
……
5.1.8 格式化字串
格式化字串是指先制定一個模板,在這個模板中預留幾個空位,然後再根據需要填上相應的內容。這些空位需要通過制定的符號標記(也稱為佔位符),而這些符號還不會顯示出來。在Python 中,格式化字串有以下兩種方法:
1. 使用“%”操作符
在Python 中,要實現格式化字串,可以使用“%” 操作符,語法格式如下:
'%[-][+][0][m][.n]格式化字元'%exp
引數說明:
- -:可選引數,用於指定左對齊,證書前方無符號,負數前方加負號。
- +:可選引數,用於指定右對齊,正數前方加正號,負數前方加負號。
- 0:可選引數,表示右對齊,正數前方無符號,負數前方加負號,用0填充空白處(一般與m 引數一起使用) 。
- m:可選引數,表示佔有寬度。
- .n:可選引數,表示小數點後保留的位數。
- 格式化字元:用於指定型別,其值如下邊所示。
格式化字元 | 說明 | 格式化字元 | 說明 |
%s | 字串(採用str())顯示 | %r | 字串(採用repr()顯示) |
%c | 單個字元 | %o | 八進位制整數 |
%d 或者 %i | 十進位制整數 | %e | 指數(基底寫為e) |
%x | 十六進位制整數 | %E | 指數(基底寫為E) |
%f 或者 %F | 浮點數 | %% | 字元% |
- exp:要轉換的項。如果要指定的項有多個,需要通過元組的形式進行指定,但不能使用列表。
例如,格式化輸出一個儲存公司資訊的字串,程式碼如下:
template = '編號:%09d\t公司名稱: %s \t官網:http://www.%s.com'# 定義模板 context1 = (7,'百度','baidu')# 定義要轉換的內容1 context2 = (8,'部落格園','cnblogs')# 定義要轉換的內容2 print(template%context1)# 格式化輸出 print(template%context2)# 格式化輸出
上面的程式碼執行後將顯示下面效果,即按照指定模板格式輸出兩條公司資訊。
編號:00007公司名稱: 百度官網:http://www.baidu.com 編號:00008公司名稱: 部落格園官網:http://www.cnblogs.com
說明:由於使用% 操作符是早期Python 中提供的方法,自從Python 2.6版本開始,字串物件提供了format() 方法對字串進行格式化。現在一些Python 社群也推薦使用這種方法。所以建議大家重點學校format() 方法的使用。
2. 使用字串物件的format() 方法
字串物件提供了format() 方法用於進行字串格式化,語法格式如下:
str.format(args)
引數說明:
- str: 用於指定字串的顯示樣式(即模板)。
- args:用於指定要轉換的項,如果有多項,則用逗號進行分隔。
下面重點介紹建立模板。在建立模板時,需要使用“{}”和“:”指定佔位符,語法格式如下:
{[index][:[fill]align][sign][#][width][.precision][type]]}
引數說明:
- index:可選引數,用於指定要設定格式的物件在引數列表中的索引位置,索引值從0開始。如果省略,則根據值的先後順序自動分配。
- fill:可選引數,用於指定空白處填充的字元。
- align:可選引數,用於指定對齊方式(值為“<”是表示內容左對齊;值為“>”時表示內容右對齊;值為“=”時表示內容右對齊,將符合放在填充內容的最左側,且值對數字型別有效;值為“^”時表示內容居中),需要配合width一起。
- sign:可選引數,用於指定有無符號數(值為“+”表示正數加正號,負數加負號;值為“-”表示正數不變;負數加負號,值為空格表示正數加空格,負數加負號)。
- #:可選引數,對於二進位制數、八進位制數和十六進位制數,如果加上#,表示會顯示0b/0o/0x字首,否則不顯示字首。
- width:可選引數,用於指定所佔寬度。
- .precision:可選引數,用於指定保留的小數位數。
- type:可選引數,用於指定型別。
format() 方法中常用的格式化字元如下:
格式化 | 說明 | 格式化字元 | 說明 |
s | 對字串型別格式化 | b | 將十進位制整數自動轉換成二進位制表示再格式化 |
d | 十進位制整數 | o | 將十進位制整數自動轉換成八進位制表示再格式化 |
c | 將十進位制整數自動轉換成對應的Unicode字元 | x 或者 X | 將十進位制整數自動轉換成十六進位制表示再格式化 |
e 或者 E | 轉換為科學計數法表示再格式化 | f 或者 F | 轉換為浮點數(預設小數點後保留6位)再格式化 |
g 或者 G | 自動在 e 和 f 或者 E 和 F 中切換 | % | 顯示百分比(預設顯示小數點後6位) |
說明:當一個模板中,出現多個佔位符時,指定索引位置的規範需統一,即全部採用手動指定,或者全部採用自動。例如,定義“'我是數值:{:d},我是字串:{1:s}'” 模板是錯誤的。
例如,定義一個儲存公司資訊的字串模板,然後應用該模板輸出不同公司的資訊,程式碼如下:
template = '編號:{:0>9s}\t公司名稱: {:s} \t官網:http://www.{:s}.com'# 定義模板 context1 = template.format('7','百度','baidu')# 轉換的內容1 context2 = template.format('8','部落格園','cnblogs')# 轉換的內容2 print(context1)# 輸出格式化後的字串 print(context2)# 輸出格式化後的字串
上面程式碼執行後如下:
編號:000000007公司名稱: 百度官網:http://www.baidu.com 編號:000000008公司名稱: 部落格園官網:http://www.cnblogs.com
在實際開發中,數值型別有多種顯示方式,比如貨幣形式、百分比形式等,使用format() 方法可以將數值格式化為不同的形式。下面通過一個具體的例項進行說明。
例項06:格式化不同的數值型別資料
將不同型別的資料進行格式化並輸出,程式碼如下:
import math# 匯入Python的數字模組 # 以貨幣形式顯示 print('51234+12354的結果是(以貨幣形式顯示):¥{:,.2f}元'.format(51234+12354)) print('{0:.1f}用科學計數法表示:{0:E}'.format(120000.1))# 用科學計數法表示 print('π取5位小數:{:.5f}'.format(math.pi))# 輸出小數點後五位 print('{0:d}的16進位制結果是:{0:#x}'.format(100))# 輸出十六進位制 # 輸出百分比,並且不帶小數 print('天才是由{:.0%}的靈感,加上{:.0%}的汗水。'.format(0.01,0.99))
執行例項,將顯示如下結果。
51234+12354的結果是(以貨幣形式顯示):¥63,588.00元 120000.1用科學計數法表示:1.200001E+05 π取5位小數:3.14159 100的16進位制結果是:0x64 天才是由1%的靈感,加上99%的汗水。
5.2 字串編碼轉換
……在Python 3.X 中,預設採用的編碼格式為UTF-8,採用這種編碼有效地解決了中文亂碼的問題。
在Python 中,有兩種常用的字串型別,分別為str 和bytes。其中,str 表示Unicode 字元(ASCII 或者其他);bytes 表示二進位制資料(包括編碼的文字)。這兩種型別的字串不能拼接在一起使用。通常情況下,str 在記憶體中以 Unicode 表示,一個字元對應若干個位元組。但是如果在網路上傳輸,或者儲存到磁碟上,就需要把str 轉換為位元組型別,即bytes 型別。
說明:bytes型別的資料是帶有b 字首的字串(用單引號或雙引號表示),例如,b'\xd2\xb0'和b'mr' 都是bytes型別的資料。
str型別和bytes型別之間可以通過encode() 和 decode() 方法進行轉換,這兩個方法是互逆的過程。
5.2.1 使用encode() 方法編碼
encode() 方法為 str 物件的方法,用於將字串轉換為二進位制資料(即bytes),也稱為“編碼”,其語法格式如下:
str.encode([encoding="utf-9"][,errors="strict"])
引數說明:
- str:表示要進行轉換的字串。
- encoding="utf-8" :可選引數,用於指定進行轉碼時採用的字元編碼,預設為UTF-8,如果想使用簡體中文,也可以設定為gb2312。當只有這一個引數時,也可以省略前面的“encoding=”,直接寫編碼。
- errors=“strict”:可選引數,用於指定錯誤處理方式,其可選擇值可以是strict(遇到非法字元就丟擲異常)、ignore(忽略非法字元)、replace(用“?”替換非法字元)或xmlcharrefreplace(使用XML 的字元引用)等,預設值為strict。
說明:在使用encode() 方法時,不會修改原字串,如果需要修改原字串,需要對其進行重新賦值。
例如,定義一個名稱為verse 的字串,內容為“野渡無人舟自橫”,然後使用endoce() 方法將其採用GBK 編碼轉換為二進位制數,並輸出原字串和轉換後的內容,程式碼如下:
verse = '野渡無人舟自橫' byte = verse.encode('GBK')# 採用GBK編碼轉換為二進位制資料,不處理異常 print('原字串:',verse)# 輸出原字串(沒有改變) print('轉換後:',byte)# 輸出轉換後的二進位制資料
上面的程式碼執行後,將顯示以下內容:
原字串: 野渡無人舟自橫 轉換後: b'\xd2\xb0\xb6\xc9\xce\xde\xc8\xcb\xd6\xdb\xd7\xd4\xba\xe1'
如果採用UTF-8 編碼,轉換後的二進位制資料為:
原字串: 野渡無人舟自橫 轉換後: b'\xe9\x87\x8e\xe6\xb8\xa1\xe6\x97\xa0\xe4\xba\xba\xe8\x88\x9f\xe8\x87\xaa\xe6\xa8\xaa'
5.2.2 使用decode() 方法編碼
decode() 方法為bytes 物件的方法用於將二進位制資料轉換為字串,即將使用encode() 方法轉換的結果再轉換為字串,也稱為“解碼”。語法格式如下:
bytes.decode([encoding="utf-8"][,errors="strict"])
引數說明:
- bytes:表示要進行轉換的二進位制資料,通常是encode() 方法轉換的結果。
- encoding="utf-8" :可選引數,用於指定進行解碼時採用的字元編碼,預設為UTF-8,如果想使用簡體中文,也可以設定為gb2312。當只有這一個引數時,也可以省略前面的“encoding=”,直接寫編碼。
注意:在設定解碼採用的字元編碼時,需要與編碼時採用的字元編碼一致。
- errors=“strict”:可選引數,用於指定錯誤處理方式,其可選擇值可以是strict(遇到非法字元就丟擲異常)、ignore(忽略非法字元)、replace(用“?”替換非法字元)或xmlcharrefreplace(使用XML 的字元引用)等,預設值為strict。
說明:在使用decode() 方法時,不會修改原字串,如果需要修改原字串,需要對其進行重新賦值。
例如,將5.2.1 小節中的示例編碼後會得到二進位制資料(儲存在變數byte 中),要進行解碼可以使用下面的程式碼:
verse = '野渡無人舟自橫' byte = verse.encode('GBK')#採用GBK編碼轉換為二進位制資料,不處理異常 print('解碼後:',byte.decode("GBK"))# 對進行制資料進行解碼
上面的程式碼執行後,將顯示以下內容:
解碼後: 野渡無人舟自橫
5.3 正則表示式
在處理字串時,經常會有查詢符合某些賦複雜規則的字串的需求。正則表示式就是用於描述這些規則的工具。換句話說,正則表示式就是記錄文字規則的程式碼。對於接觸過DOS 的使用者來說,如果想匹配當前資料夾下所有的文字檔案,可以輸入“dir *.txt” 命令,按<Enter>鍵後,所有“.txt” 檔案將會被列出來。這裡的“*.txt” 即可理解為一個簡單的正則表示式。
5.3.1 行定位符
行定位符就是用來描述字串的邊界,“^” 表示行的開始,“$” 表示行的結尾。如:
^tm
該表示式表示要匹配字串tm 的開始位置是行頭,如“tm equal Tomorrow Moon” 可以匹配,而“Tomorrow Moon equal tm” 則不匹配。但如果使用:
tm$
後者可以匹配而前者不能匹配。如果要匹配的字串可以出現在字串的任意部分,那麼可以直接寫成下面的格式,這樣兩個字串就都可以匹配了。
tm
5.3.2 元字元
除了前面介紹的元字元“^” 和“$” 外,正則表示式裡還有更多的元字元,例如下面的正則表示式中就應用了元字元“\b” 和“\w”。
\bmr\w*\b
上面的正則表示式用於匹配以字母mr 開頭的單詞,先從某個單詞開始處(\b),然後匹配字母mr,接著是任意數量的字母或數字(\w*),最後單詞結束處(\b)。該表示式可以匹配“mrsoft” “nmr” 和“mr123456等,但不能與“amr”匹配。更多常用元素符見下表。
程式碼 | 說明 |
舉例 |
. | 匹配除換行符以外的任意字元 |
. 可以匹配“mr\nM\tR”中的m、r、M、\t、R |
\w | 匹配字母、數字、下劃線或漢字 |
\w 可以匹配“m 中 7r\n”中的“m、中、7、r”,但 不能匹配\n |
\W | 匹配除字母、數字、下劃線或漢字以外的字元 |
\W 可以匹配“m 中 7r\n”中的“n,但不能匹配“m、中、7、r” |
\s | 匹配單個的空白符(包括Tab鍵和換行符) |
\s 可以匹配“mr\tMR”中的\t |
\S |
除單個空白符(包括Tab鍵和換行符)以外的 所有字元 |
\S 或可以匹配“mr\tMR”中的m、r、M、R |
\b |
匹配單詞的開始或結束,單詞的分解符通常是 空格,標點符號或者換行 |
在“I like mr or am”字串中,\bm與mr中的m相匹配,但與 am中的m 不匹配 |
\d | 匹配數字 |
\d 可以與“m7ri” 中的字元7 匹配 |
5.3.3 限定符
在上面例子中,使用(\w*)匹配任意數量的字母或數字。如果想匹配特定數量的數字,該如何表示呢?正則表示式為我們提供了限定符(指定數量的字元)來實現該功能。如匹配8 位QQ 號可以如下表達式:
^\d{8}$
常見的限定符見下表
……
5.3.4 字元類
……
5.3.5 排除字元
……
5.3.6 選擇字元
……
5.3.7 轉義字元
……
5.3.8 分組
……
5.3.9 在Python中使用正則表示式語法
……
5.4 使用 re 模組實現正則表示式操作
……
5.4.1 匹配字串
匹配字串可以使用re 模組提供的match()、search() 和findall() 等方法。
1. 使用match() 方法進行匹配
match() 方法用於從字串的開始處進行匹配,如果在起始位置匹配成功,則返回Match 物件,否則返回None。其語法格式如下:
re.match(pattern,string,[flags])
引數說明:
- pattern:表示模式字串,由要匹配的正則表示式轉換而來。
- string:表示要匹配的字串。
- flags:可選引數,表示標誌位,用於控制匹配方式,如是否區分字母大小寫。常用的標誌如表5.5 所示。
標誌 | 說明 |
……
例項07:
……
2. 使用search() 方法進行匹配
search() 方法用於在整個字串中搜索第一個匹配的值,如果匹配成功,則返回Match物件,否則返回None。search() 方法的語法格式如下:
re.search(pattern,string,[flags])
引數說明:
- pattern:表示模式字串,由要匹配的正則表示式轉換而來。
- string:表示要匹配的字串。
- 可選引數,表示標誌位,用於控制匹配方式,如是否區分字母大小寫。常用的標誌如表5.5所示。
例如,搜尋第一個以“mr_” 開頭的字串,不區分字母大小寫,程式碼如下:
……
例項08:
……
3. 使用findall() 方法進行匹配
findall() 方法用於在整個字串中搜索所有符合正則表示式的字串,並以列表的形式返回。如果匹配成功,則返回包含匹配結構的列表,否則返回空列表。findall() 方法的語法格式如下:
re.findall(pattern,string,[flags])
引數說明:
pattern:表示模式字串,由要匹配的正則表示式轉換而來。
string:表示要匹配的字串。
flags:可選引數,表示標誌位,用於控制匹配方式,如是否區分字母大小寫。常用的標誌如5.5所示。
例如,搜尋以“mr_” 開頭的字串,程式碼如下:
……
5.4.2 替換字串
sub() 方法用於實現字串替換,語法格式如下:
re.sub(pattern,repl,string,count,flags)
引數說明:
- pattern:表示模式字串,由要匹配的正則表示式轉換而來。
- repl:表示替換的字串。
- string:表示要被查詢替換的原始字串。
- count:可選引數,表示模式匹配後替換的最大次數,預設值為0,表示替換所有的匹配。
- flags:可選引數,表示標誌位,用於控制匹配方式,如是否區分字母大小寫。常用的標誌如表5.5所示。
例如,隱藏中獎資訊中的手機號碼,程式碼如下:
import re pattern = r'1[34578]\d{9}'# 定義要替換的模式字串 string = '中獎號碼為:468451646546 聯絡電話:13855556666' result = re.sub(pattern,'1xxxxxxxxxx',string)# 替換字串 print(result)
執行結果如下:
中獎號碼為:468451646546 聯絡電話:1xxxxxxxxxx
例項09:替換出現的危險字元
……
5.4.3 使用正則表示式分割字串
split() 方法用於實現根據正則表示式分割字串,並以列表的形式返回。其作用同字串物件的split() 方法類似,所不同的就是分割字元由模式字串指定。split() 方法的語法格式如下:
re.split(pattern,string,[maxsplit],[flags])
引數說明:
- pattern:表示模式字串,由要匹配的正則表示式轉換而來。
- string:表示要匹配的字串。
- maxsplit:可選引數,表示最大的拆分次數。
- flags:可選引數,表示標誌位,用於控制匹配方式,如是否區分字母大小寫。常用的標誌如5.5所示。
例如,從給定的URL地址中提取出請求地址和各個引數,程式碼如下:
import re pattern = r'[?|&]'# 定義分隔符 url = 'http://www.mingrisoft.com/login.jsp?username="mr"&pwd="mrsoft"' result = re.split(pattern,url)# 分割字串 print(result)
執行結果如下:
['http://www.mingrisoft.com/login.jsp', 'username="mr"', 'pwd="mrsoft"']
場景模擬:……
例項10:輸入被@的好友名稱(應用正則表示式)
……
5.5 實戰
……