一、前言
大家好,我是更新看緣分的李鵬李先生。
本次課程主講 Python 中的字符串,閑話少說,直接開始。
本文約3500字,閱讀需15分鐘左右,祝大家閱讀愉快。
二、字符串
在學(xué)習(xí)今天的內(nèi)容之前,我們要首先了解一下到底什么是字符串。
我們平常說的話,和別人溝通交流的語言其實就是字符串。
只不過在 Python 當(dāng)中,字符串演變成了一種數(shù)據(jù)類型,但是我們雖然知道了字符串演變成了一種數(shù)據(jù)類型,
可是這種類型在計算機當(dāng)中是如何來使用的呢?我想在計算機中使用中文行不行呢?
接下來我們首先來探究一下 Python 中編碼格式的問題。
2.1 ASCII 編碼
首先聲明,計算機底層當(dāng)中不能接收中文,甚至連文本都無法處理。
必須要轉(zhuǎn)換成數(shù)字來進行表示,也就是我們常說的字節(jié)。
需要注意:
- 1 字節(jié)(byte) = 8 比特(bit)
- 一個字節(jié)能表示的最大的整數(shù)就是255(即二進制11111111)
- 兩個字節(jié)可以表示的最大整數(shù)是65 535
- 四個字節(jié)可以表示的最大整數(shù)是4 294 967 295
最開始的計算機,就只保存了127個字符在計算機里面,其中包含了數(shù)字、字母、特殊符號等等。
而這個表則統(tǒng)稱為 ASCII編碼。
其中我們需要注意的就是我們需要記住的就只有其中三個。
| 十進制表示 | 內(nèi)容 | 含義 |
|---|---|---|
| 48 | 0 | 數(shù)字 0 |
| 65 | A | 字母 A (大寫) |
| 97 | a | 字母 a (小寫) |
通過記住這三個內(nèi)容,我們可以分別推出 0 ~ 9、A ~ Z、a ~ z 的 ASCII 編碼數(shù)字。
2.2 Unicode
既然有了 ASCII 編碼,那是不是就完事大吉了呢?
當(dāng)然不是,如果中國有自己的編碼表(GB2312編碼),日本也有自己的編碼表(Shift_JIS),韓國也有韓文編碼表(Euc-kr),那豈不是天下大亂?
你在中國寫的東西,到日本,到韓國就直接變成了一堆亂碼,那我相信,我們的工作生活將會受到極大的影響。
那么這時候我們該怎么辦呢?
這時候國際標(biāo)準(zhǔn)化組織(ISO)和多語言軟件制造商組成的統(tǒng)一碼聯(lián)盟站了出來,他們聯(lián)合其他機構(gòu)進行了統(tǒng)一化的工作,而統(tǒng)一化的結(jié)果就是我們熟知的 Unicode 編碼。
通過 Unicode,就可以實現(xiàn)在不同國家之間,可以將文字和語言相通啦。
但是部分國家使用的都是漢字,而某些國家日常通信使用的都是英文,這里面其實有很大的差別。
要知道漢字已經(jīng)超出了ASCII編碼的范圍,并且大部分需要使用兩個字節(jié)來表示,有些甚至需要四個四節(jié),而英文只需要一個字節(jié)即可。
字母
A用ASCII編碼是十進制的65,二進制的01000001;字符
0用ASCII編碼是十進制的48,二進制的00110000,注意字符'0'和整數(shù)0是不同的;漢字
中已經(jīng)超出了ASCII編碼的范圍,用Unicode編碼是十進制的20013,二進制的01001110 00101101。
那我們是不是就應(yīng)該在書寫中文相關(guān)的內(nèi)容時,需要使用 Unicode 編碼,
書寫通篇是英文或者數(shù)字的時候,應(yīng)該優(yōu)先使用 ASCII 編碼。
這時候我們就要講到一個新的標(biāo)準(zhǔn),UTF-8啦。
2.3 UTF-8
由于為了要節(jié)省空間,應(yīng)該使用ASCII 編碼的內(nèi)容就不應(yīng)該去使用 Unicode 編碼。
A 的 ASCII 編碼:01000001
A 的 Unicode 編碼:00000000 01000001
那計算機怎么區(qū)分什么時候應(yīng)該使用Unicode 編碼,什么時候使用 ASCII 編碼呢?
為了解決這個問題,出現(xiàn)了一種中間格式的字符集,即UTF(Unicode Transformation Format)。
常見的UTF格式有:
- UTF-7
- UTF-7.5
- UTF-8
- UTF-16
- UTF-32
其中我們需要重點了解的就是 UTF-8編碼,即“可變長的編碼”。
UTF-8編碼把一個Unicode字符根據(jù)不同的數(shù)字大小編碼成1-6個字節(jié),
常用的英文字母被編碼成1個字節(jié),漢字通常是3個字節(jié),很生僻的字符會被編碼成4-6個字節(jié)。
這里需要注意一點:
Python的誕生比Unicode標(biāo)準(zhǔn)發(fā)布的時間還要早,所以最早的Python只支持ASCII編碼,
普通的字符串'ABC'在Python內(nèi)部都是ASCII編碼的。
而使用UTF-8編碼還有一個額外的好處,就是ASCII編碼實際上可以被看成是UTF-8編碼的一部分,
所以,大量只支持ASCII編碼的歷史遺留軟件可以在UTF-8編碼下繼續(xù)工作。
這也就是為什么我們每次在使用中文的時候都需要在文件開頭聲明 UTF-8 啦。
2.4 字符串的“切片”
當(dāng)我們弄明白編程中令人苦惱的編碼格式之后,我們就可以去使用我們的字符串啦。
例如我現(xiàn)在聲明一個變量 name。
name = "lipeng"
那有一天我的學(xué)生霏姐想惡搞一下我,想把我名字中的一部分抽出來,這時候其實就要用到“切片”啦。
需要注意,字符串、列表、元組都支持切片操作。
首先先來說一下切片的語法:
切片的語法:[起始:結(jié)束:步長]
注意: 選取的區(qū)間屬于左閉右開型,即從"起始"位開始,到"結(jié)束"位的前一位結(jié)束(不包含結(jié)束位本身)。
那接下來來一個實際例子。
Last login: Tue Aug 7 09:27:48 on ttys000
? ~ python
>>> name = "lipeng"
>>> print(name[0:3])
lip
>>>
我們?nèi)〉搅讼聵?biāo)0~2 的字符,那接下來我們測試一下0~4的字符。
Last login: Tue Aug 7 09:27:48 on ttys000
? ~ python
>>> name = "lipeng"
>>> print(name[0:5])
lipen
>>>
再來一個3~4的字符。
Last login: Tue Aug 7 09:27:48 on ttys000
? ~ python
>>> name = "lipeng"
>>> print(name[3:5])
en
>>>
那如果我們需要從某一個位置之后所有的數(shù)據(jù)呢?
Last login: Tue Aug 7 09:27:48 on ttys000
? ~ python
>>> name = "lipeng"
>>> print(name[2:])
peng
>>>
再假設(shè),我們現(xiàn)在不知道總共內(nèi)容有多長,但是知道需要截取到末尾的第幾個,這時候應(yīng)該怎么辦呢?
Last login: Tue Aug 7 09:27:48 on ttys000
? ~ python
>>> name = "lipeng"
>>> print(name[1:-1])
ipen
>>>
如果你覺得自己已經(jīng)明白切片的用法的話,可以自己試試以下題目:
>>> print(name[:3])
lip
>>> print(name[::2])
lpn
>>> print(name[5:1:2])
"" # 空
>>> print(name[1:5:2])
ie
>>> print(name[::-2])
gei
>>> print(name[5:1:-2])
ge
>>>
2.5 字符串中常用的方法
2.5.1 ord( ) : 獲取字符的整數(shù)表示
? ~ python
>>> ord('a')
97
>>> ord('A')
65
>>> ord('0')
48
>>>
2.5.2 chr( ):編碼轉(zhuǎn)換為對應(yīng)的字符
>>> chr(69)
'E'
>>> chr(103)
'g'
>>>
2.5.3 find( ):查詢是否有對應(yīng)文本
檢測 str 是否包含在 mystr中,如果是返回開始的索引值,否則返回-1。
標(biāo)準(zhǔn)語法:mystr.find(str, start=0, end=len(mystr))
>>> name = "my name is MR_LP"
>>> name.find("MR_LP")
11
>>>
2.5.4 index( ):查詢是否有對應(yīng)文本
檢測 str 是否包含在 mystr中,如果是返回開始的索引值,否則報錯
標(biāo)準(zhǔn)語法:mystr.index(str, start=0, end=len(mystr))
>>> name = "my name is MR_LP"
>>> name.index("MR_LP")
11
>>> name.index("ZZZ")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: substring not found
>>>
2.5.5 count( ):返回字符出現(xiàn)的次數(shù)
返回 str在start和end之間 在 mystr里面出現(xiàn)的次數(shù)
標(biāo)準(zhǔn)語法:mystr.count(str, start=0, end=len(mystr))
>>> name = "my name is MR_LP"
>>> name.count('m')
2
>>>
2.5.6 replace( ):替換文本,替換不超過 count 次
把 mystr 中的 str1 替換成 str2,如果 count 指定,則替換不超過 count 次.
標(biāo)準(zhǔn)語法:mystr.replace(str1, str2, mystr.count(str1))
>>> name = "my name is MR_LP"
>>> name.replace("MR_LP","233")
'my name is 233'
>>> name.replace("m","233",1)
'233y name is MR_LP'
>>>
2.5.7 split( ):按照分隔符將字符串切片
以 str 為分隔符切片 mystr,如果 maxsplit有指定值,則僅分隔 maxsplit 個子字符串
標(biāo)準(zhǔn)語法:mystr.split(str=" ", 2)
>>> name = "my name is MR_LP"
>>> name.split(' ')
['my', 'name', 'is', 'MR_LP']
>>> name.split(' ',2)
['my', 'name', 'is MR_LP']
>>>
2.5.8 capitalize( ):字符串首字母大寫
把字符串的第一個字符大寫
標(biāo)準(zhǔn)語法:mystr.capitalize()
>>> name = "my name is MR_LP"
>>> name.capitalize()
'My name is mr_lp'
>>>
2.5.9 title( ):字符串中每個單詞首字母大寫
把字符串的每個單詞首字母大寫
標(biāo)準(zhǔn)語法:name.title()
>>> name = "my name is MR_LP"
>>> name.title()
'My Name Is Mr_Lp'
>>>
2.5.10 startswith( ):檢測字符串是否以某內(nèi)容開頭
檢查字符串是否是以 obj 開頭, 是則返回 True,否則返回 False
標(biāo)準(zhǔn)語法:mystr.startswith(obj)
>>> name = "my name is MR_LP"
>>> name.startswith('my')
True
>>> name.startswith('My')
False
>>>
2.5.11 endswith( ):檢測字符串是否以某內(nèi)容結(jié)尾
檢查字符串是否是以 obj 結(jié)尾, 是則返回 True,否則返回 False
標(biāo)準(zhǔn)語法:mystr.endswith(obj)
>>> name = "my name is MR_LP"
>>> name.endswith('LP')
True
>>> name.endswith('lp')
False
>>>
2.5.12 lower( ):大寫字符為小寫
轉(zhuǎn)換 mystr 中所有大寫字符為小寫
標(biāo)準(zhǔn)語法:mystr.lower()
>>> name = "my name is MR_LP"
>>> name.lower()
'my name is mr_lp'
>>>
2.5.13 所有大寫字符為大寫
轉(zhuǎn)換 mystr 中所有大寫字符為大寫
標(biāo)準(zhǔn)語法:mystr.upper()
>>> name = "my name is MR_LP"
>>> name.upper()
'MY NAME IS MR_LP'
>>>
2.5.14 ljust( ):左對齊并填充字符串
返回一個原字符串左對齊,并使用空格填充至長度 width 的新字符串
標(biāo)準(zhǔn)語法:mystr.ljust(width)
>>> s = "lipeng"
>>> s.ljust(10)
'lipeng '
>>>
2.5.15 rjust( ):右對齊并填充字符串
返回一個原字符串右對齊,并使用空格填充至長度 width 的新字符串
標(biāo)準(zhǔn)語法:mystr.rjust(width)
>>> s = "lipeng"
>>> s.rjust(10)
' lipeng'
>>>
2.5.16 center( ):居中對齊并填充字符串
返回一個原字符串居中,并使用空格填充至長度 width 的新字符串
標(biāo)準(zhǔn)語法:mystr.center(width)
>>> s = "lipeng"
>>> s.center(20)
' lipeng '
>>>
2.5.17 lstrip( ):清除左側(cè)空白字符
刪除 mystr 左邊的空白字符
標(biāo)準(zhǔn)語法:mystr.lstrip()
>>> str = ' lipeng '
>>> str.lstrip()
'lipeng '
>>>
2.5.18 rstrip( ):清除右側(cè)空白字符
刪除 mystr 右邊的空白字符
標(biāo)準(zhǔn)語法:mystr.rstrip()
>>> str = ' lipeng '
>>> str.rstrip()
' lipeng'
>>>
2.5.19 strip( ):清除左右兩側(cè)空白字符
刪除 mystr 兩側(cè)的空白字符
標(biāo)準(zhǔn)語法:mystr.strip()
>>> str = ' lipeng '
>>> str.strip()
'lipeng'
>>>
2.5.20 rfind( ):從右側(cè)查詢是否有對應(yīng)文本
從右側(cè)查詢是否有對應(yīng)文本
標(biāo)準(zhǔn)語法:mystr.rfind(str, start=0,end=len(mystr) )
>>> name = "lipeng"
>>> name.rfind("p")
2
>>>
2.5.21 rindex( ):從右側(cè)查詢是否有對應(yīng)文本
和 index( ) 相同,但是是從右側(cè)開始
標(biāo)準(zhǔn)語法:mystr.rindex( str, start=0,end=len(mystr))
>>> name = "lipeng"
>>> name.rindex("e")
3
>>> name.rindex("LI")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: substring not found
>>>
2.5.22 partition( ):以對應(yīng)文本將字符串分割成三部分
把mystr以str分割成三部分,str前,str和str后
標(biāo)準(zhǔn)語法:mystr.partition(str)
>>> s = "i'm lipeng, you can call me MR_LP"
>>> s.partition("can")
("i'm lipeng, you ", 'can', ' call me MR_LP')
>>>
2.5.23 rpartition( ):從右側(cè)以對應(yīng)文本將字符串分割成三部分
從右側(cè)把mystr以str分割成三部分,str前,str和str后
標(biāo)準(zhǔn)語法:mystr.rpartition(str)
>>> s = "i'm lipeng, you can call me MR_LP"
>>> s.rpartition("can")
("i'm lipeng, you ", 'can', ' call me MR_LP')
>>>
2.5.24 splitlines( ):按行分割
按照行分隔,返回一個包含各行作為元素的列表
標(biāo)準(zhǔn)語法:mystr.splitlines()
>>> s = "MR_LP.\nmr_lp"
>>> print(s)
MR_LP.
mr_lp
>>> s.splitlines()
['MR_LP.', 'mr_lp']
>>>
2.5.25 isalpha( ):判斷是否全部是字母
如果 mystr 所有字符都是字母 則返回 True,否則返回 False
標(biāo)準(zhǔn)語法:mystr.isalpha()
>>> s = "abc"
>>> s.isalpha()
True
>>> s = "123"
>>> s.isalpha()
False
>>> s = "abc 123"
>>> s.isalpha()
False
2.5.26 isdigit( ):判斷是否全部是數(shù)字
如果 mystr 只包含數(shù)字則返回 True 否則返回 False.
標(biāo)準(zhǔn)語法:mystr.isdigit()
>>> s = "abc"
>>> s.isdigit()
False
>>> s = "123"
>>> s.isdigit()
True
>>> s = "abc123"
>>> s.isdigit()
False
2.5.27 isalnum( ):判斷是否全部是數(shù)字或字母
如果 mystr 所有字符都是字母或數(shù)字則返回 True,否則返回 False
標(biāo)準(zhǔn)語法:mystr.isalnum()
>>> s = "123"
>>> s.isalnum()
True
>>> s = "abc"
>>> s.isalnum()
True
>>> s = "abc123"
>>> s.isalnum()
True
>>> s = "abc 123"
>>> s.isalnum()
False
2.5.28 isspace( ):判斷是否只包含空格
如果 mystr 中只包含空格,則返回 True,否則返回 False.
標(biāo)準(zhǔn)語法:mystr.isspace()
>>> s = "abc123"
>>> s.isspace()
False
>>> s = ""
>>> s.isspace()
False
>>> s = " " # 空格
>>> s.isspace()
True
>>> s = " " # tab 鍵
>>> s.isspace()
True
2.5.28 join( ):判斷是否只包含空格
如果 mystr 中只包含空格,則返回 True,否則返回 False.
標(biāo)準(zhǔn)語法:mystr.isspace()
>>> s = " "
>>> li = ["my","name","is","LIPENG"]
>>> s.join(li)
'my name is LIPENG'
>>> s = "_"
>>> li = ["my","name","is","LIPENG"]
>>> s.join(li)
'my_name_is_LIPENG'