1.基本語法
(1)加法的兩端只能是數字或者字符串。
如 print( 'kkk' + 12 + 'kkk' ) 是錯誤的,可修改為 print( 'kkk' + str(12) + 'kkk' ) 。類似 str() 的函數還有 int(),float()。
print(str(0)) #輸出字符串的0 print(int('33')) print(int(3.26)) #輸出3 print(float(3.402)) print(float(23)) #輸出23.0
print(int(input()))
(2)在用於條件時,0、0.0、和 ' ' (空字符串) 被當作False,其他值被當作 True
name = '' while not name: #只有輸入有效的名字才跳出循環 name = input() print('your name:' + name)
name = 0 while not name: name = int(input()) print('最終結果:' + str(name)) #輸入非0整數結束
2.數學操作符
- 指數:**。如 2 ** 3 = 8。
- 整除://。如 6 // 4 = 1。
- 除法:/。如 6 / 4 = 1.5。
- * 操作符表示乘法,但是當 * 和字符串連用時,表示將字符串復制的操作。如
print('Jack' * 2) #輸出JackJack。同時注意 只能同整數配套使用
- 其他操作同 C 語言一致。
3.布爾操作符
and,not,or 代替了 C 語言的 && 和 ||
4.控制流
(1)if-else: 關鍵是通過控制代碼塊的縮進距離,Python沒有花括號
name = 'Jack' age = 2 if(name == 'Jack'): print('Hello,Jack') if(age > 10): print('>10') else: print('<10') else: print('Who are you?')
(2)while 循環
age = 5 while age < 9: age += 1 #不支持 age++ print('age: ' + str(age)) if(age == 7): break print('end')
sum = 0 while True: if sum == 3: print('錯誤次數超過三次!') break else: name = input() if name != '11': sum += 1 print('用戶名錯誤,重新輸入用戶名:') continue else: print('用戶名正確,輸入密碼:') pwd = input() if pwd != '11': print('密碼錯誤,重新輸入用戶名:') sum += 1 continue
(3)for 循環。range(開始,停止【不包括它】,步長)
i = 0 for i in range(0,10,2): print(i) #0,2,4,6,8
5.字符串(也是列表)
(1)字符串相等否,可直接用 == 或者 != 判斷
a = 'q' s = 'qq' if a != s: print("yes") else: print("no")
(2)字符串的截取。同 C 語言的差別就是標號的不一致
如上圖所示,即 ‘abcdef’ 的下表是 0~5 或者 -6~-1。同時規則也常用:前閉后開。
str = 'abcdef' print(str[0] + str[2]) #ac print(str[-6] + str[-1]) #af print(str[0:]) #abcdef print(str[-3:]) #def print(str[0:3]) #abc print(str[3:2]) #無結果 不能逆序 print(str[1:-1]) #bcde print(str[-6:2]) #ab
print(str[:2]) #ab
print(str[:]) #abcdef
(3)同樣可使用 in 和 not in 操作符
str = '12345ddd6789' print('ddd' in str) #True print('012' not in str) #True
(4)數組是可變的,如append、insert、del等,但是字符串是 “不可變” ,如 str[0] = 'd' ,改變的方式是通過切邊方式
str = '123456789' str2 = str[0:2] + 'add' + str[6:8] print(str2) #12add78
(5)字符串的輸入。輸入單引號、取消轉義、多行字符串
#輸入單引號 str = 'daf\'fdaf' str2 = "fdaf'fda" #因為\是轉義符的意思,如果取消轉義。即直接輸出\ str3 = r'daf\'fdaf' print(str, str2, str3, sep='*****') #多行字符串。文本什么格式,輸出也什么格式,一模一樣 str4 = '''fdasfads\sssa dsf'fdsa"\dfadasf fadsfadsf''' print(str4)
(6)常用方法 upper()、lower()、isupper()、islower()。這些方法都不是改變字符串本身,而是返回了一個新字符串
和數組的例如 a.insert(0,33) 是不一樣的
str = 'fdaf898fdsa' print(str.islower()) str = str.upper() print(str) #FDAF898FDSA
(7)starswith()、endswith()。字面意思
(8)join()、split() 方法。前者參數是一個字符串列表,返回一個列表通過空格字母等串接之后的字符串。后者恰相反,傳入字符串 -->> 字符串列表
str = {'ewe', 'wrewrw', '323'} str = '&'.join(str) print(str) str2 = str.split('&') print(str2) str3 = '''fadsfas fdsaf fdsafffffff121ddds''' print(str3.split('\n')) #按照行進行分割
(9)rjust()、ljust()、center()。對其文本用,前兩者為右、左對齊,不足之處補充空格
str = '12345' print(str.rjust(10)) print(str.ljust(10)) print(str.center(10,'*')) #居中 左右補充
(10)strip()、rstrip()、lstrip()
刪除兩端空格,單刪除右 / 左邊空格。又如:str.strip( ' abc ')。指只刪除字符 ’abc‘ 的兩端空格
(11)isdecimal()、isalpha()、isalnum()。
是否只包含數字字符且非空,只包含字母字符且非空,只包含字母和數字且非空。
6.函數
(1)函數定義 def + 函數名(傳參)
def hello(name): #傳遞的參數 print('你輸入了:' + name) i = 0 for i in range(0,3,1): hello(input())
import random #導入函數,分為 import 和 from import(見補充)
def getNumber(j):
if j == 1:
print('隨機數:' + str(j))
return 'A'
elif j == 2:
print('隨機數:' + str(j))
return 'B'
else:
print('隨機數:' + str(j))
return 'C'
i = 0
for i in range(0,3,1):
r = random.randint(1,3) #random.randint函數是產生 1<=*<=3 的整數
print(getNumber(r))
(2)print() 函數。print() 函數返回值為None
temp = print('測試返回值') if temp == None: print('yes',str(temp))
print() 函數輸出形式:
print('1','2','3') #空格自動分割 print('1', end='') print('2') # print 函數自動會加入換行符,end = '' 就制止 print('1','2','3',sep='..') #輸出通過 ‘..’ 分割
(3)global 語句。同 C 語言中一致,Python 中也分局部和全局變量,如果想通過局部函數修改全局變量,可以通過 global 函數
def k1(): global t t = '已經修改1' def k2(): t = '已經修改2' t = '原始' print(t) #原始 k2() print(t) #原始 k1() rint(t)p #已經修改1
Python 中一個變量只能是局部或者全局變量,如
def k(): print(egg) #調用 K() 函數時,egg此句是全局變量,但在下一句中 egg 被重新聲明被認為是局部變量。報錯 egg = '123' egg = '444' k()
(4)try...except.. 函數
def k(divide): try: return 32 / divide except: return '報錯' print(k(3)) print(k(2)) print(k(0))
(5)函數返回多個值。書寫形式上簡單,但是返回多個值本質上返回的是一個元組,但是可通過多重賦值接受
def test(): return 'dfsa', 1221 a, b = test() print(a, b) #dfsa 1221
(6)設置默認參數
def test(t, n=2): #如果傳入2個參數,則n=2無效。否則n=2有效。默認參數必須放后面,否則會產生歧義,如此處,會分不清是t or n 沒有傳入參數 print(t * n) test(2, 5) test(2)
一個坑🕳:舉例如下:
def add_end(L=[]): L.append('end') return L print(add_end(['12', '23'])) #['12', '23', 'end'] print(add_end()) #['end'] ① print(add_end()) #['end', 'end'] ②
可以看出第一、二個例子,情況理想。但是第三個例子出現了兩個 end 。這是由於第二次調用 add_end() 啟用默認參數時,因為在①處調用之后,L= [ ] 已經被創建了,所以②處,沒有重新創建一個新的對象,而是沿用了①處創建的對象,導致一二兩處使用的默認對象是同一個。所以默認參數只能使用不變的對象。解決可如下:
def add_end(L = None): if L == None: L = [] L.append('end') return L print(add_end(['12', '23'])) #['12', '23', 'end'] print(add_end()) #['end'] print(add_end()) #['end']
(7)設置可變參數
其實設置可變參數的大部分場景,可以通過元組或者列表代以解決,但是使用可變參數稍微讓代碼優雅一些。那我就不客氣啦,不用白不用。
舉個求和例子一般寫法:
#整數求和 def test(L): sum = 0 for i in L: sum += i return sum L = [1, 2, 3, 4] print(test(L))
這種寫法的唯一看上去稍微不美妙的地方就是傳參 L 。也就是必須傳入列表。我們改造一番
#整數求和 def test(str ,*L): print(str,end='') sum = 0 for i in L: sum += i return sum print(test("改造改造:",1 ,2,3,4)) #也可傳入("dd",1,2,3,3,4,4,4)
#結果:改造改造:10
這次特意加了個 str 參數沒有別的意思,就是為了舉例說明可變參數的用法。即函數會自己匹配參數,從前往后先匹配 str-->"改造改造",隨后是 *L ,只要見到 * 號,就會主動的將后面的參數自動包裝成列表,也就是你不用提前組裝成列表了。
(8)關鍵字參數
與上面的類似,只不過形式上是 **L(雙星),這個就是會主動將你傳入的參數組裝成 dict 形式。如下:
#連接數據庫 def test(str, *L, **T): print(str, end='') print(len(L)) for i in T.keys(): print(i, T.get(i)) test("密碼位數:", 1, 2, 3, 密碼= '123', 用戶名= '123') #故意傳入1,2,3測試*L。其次不加單引號
很明顯可以看出,在便利 dict 的時候,因為**T 的存在,傳入密碼和用戶名之后,已經自動組裝成了字典形式 key-values。
密碼位數---str
1,2,3------*L
{密碼.....} --------**T
#連接數據庫 def test(str, *L, **T): print(str, end='') print(len(L)) for i in T.keys(): print(i, T.get(i)) pwd = {'密碼':'ddd'} pas = [1,2,3] test("密碼位數:", 1, 2, 3, **pwd) test("密碼位數:", *pas, **pwd) #注意寫法,如果上面test是*L,這里必須*pas,注意*號 def test2(str, L, T): print(str, end='') print(len(L)) for i in T.keys(): print(i, T.get(i)) test2("密碼位數:", pas, pwd) #不用變量參數,關鍵參數
(9)命名關鍵字
這是在關鍵詞上做進一步限制,也就是規定了傳入的 dict 參數是具體哪些,不能多傳或少傳。
1 #連接數據庫 2 def test(str, *, name, pwd): 3 print('name',name,'pwd',pwd) 4 pwd = {'name':123, 'pwd':111} 5 6 test("測試命名關鍵字:", **pwd) #不用變量參數,關鍵參數
即通過加將 * 號用逗號隔開,而 * 號之后的 name 和 pwd 就是必須要傳入的參數了。如果第四行的 pwd 改成: pwd = {'name':123, 'pwd':111, 'user':'Bob'} 多了user,會報錯。改成:pwd = {'name':123} 少了 pwd 也同樣報錯。
寫法有很多:
#連接數據庫 def test(str, *, name, pwd): # * 號是分割符 print('name',name,'pwd',pwd) test("測試命名關鍵字:", name=123, pwd=111) #不組裝pwd了,讓函數自己組裝
同時如果,我們在結合第七點 的可變參數,如果已經有了可變參數,寫法略不同,就是 不需要將在寫 * 號分隔符了,直接寫參數
1 #連接數據庫 2 def test(str, *L, name, pwd): #可變參數 3 print(str, end='') 4 print(len(L)) 5 print('name=',name,'pwd=',pwd) 6 7 test("密碼位數:", 1, 2, 3, name=123, pwd=123) #1,2,3傳入當作可變參數,函數將其組裝成列表
。這種寫法同樣在第七行只能傳入name 和 pwd 兩個key-value 多了或者少了就是報你的錯,毫不留情。
加大力度:
http://n3xtchen.github.io/n3xtchen/python/2014/08/08/python-args-and-kwargs
https://www.liaoxuefeng.com/wiki/1016959663602400/1017261630425888#0
7.列表
(1)用 len() 取得列表長度
直接通過下表修改值
a = [12, 'dd', 2]
print(len(a))
a[0] = 'ppp'
print(a)
(2)數組的連接、復制、刪除
a = [12, 'dd', 2]
b = ['14']
d = b
c = b + a
e = b * 3
print(d,c,e,sep='.....') #['14'].....['14', 12, 'dd', 2].....['14', '14', '14']
del a[0] #刪除操作
print(a) #['dd', 2]
(3)數組循環
catName = [] while True: print('請輸入第' + str(len(catName) + 1) + '只貓名字') name = input() if name == '': #直接敲回車 break catName += [name] print('共'+ str(len(catName)) + '只貓') for name in catName: #沒有使用range print(' ' + name)
catName = ['fdas','fd','ioo','wew','dfs'] for i in range(0,len(catName),2): #常用 range(len(catName)) 遍歷整個數組 print(' ' + catName[i]) #fdas ioo dfs
(4)某個值是否在數組中用,in 和 not in 判斷
import random catName = ['1','2','3','4','5'] i = 0 for i in range(0,4,1): t = random.randint(1,10) if(str(t) in catName): print(str(t),'在') if(str(t) not in catName): print(str(t),'不在')
(5)多重賦值
name = ['1','2'] t,a = name print(t,a) #輸出 1 2
(6)index() 方法,append(),insert(),remove(),sort()。以及切片取值。
name = ['1','2','1','999'] print(name.index('1')) #返回在數組中第一個出現的下標 0 name.append('4') #在列表中添加新值 print(name) #['1', '2', '1', '999', '4'] name.insert(1,'999') #在下標 1 處添加新值 print(name) #['1', '999', '2', '1', '999', '4'] name.remove('999') #刪除在數組中第一次出現的999,若不存在999則報錯 print(name) #['1', '2', '1', '999', '4'] del name[0] print(name) #['2', '1', '999', '4'] name.sort(reverse=True) #排序操作ASCII碼進行排序,可直接name.sort() print(name) #['999', '4', '2', '1']
# 切片取值
print(name[:4:2]) #['1', '1']。取前4個,每隔2個取一個
print(name[::3]) #['1', '999']。取全部數,每隔3個取一個
8.元組
(1)元組和數組十分類似,主要區別有兩點如下
- 元組輸入時使用 () 而非 [ ]
a = (1,2,3) print(a) #輸出 (1,2,3)
print(a[2]) #3
- 元組中的值不能修改,和字符串類似。所以 Python 可以以更優化的方式對待元組。同時,元組中如果之后一個值,通過加逗號來標識其是元組。(否則Python認為你只是普通括號)
a = (1,) #不加逗號,下句出錯.當元組長度只為1時使用 print(a[0])
(2)用 list 和 tuple 函數來轉換類型
常用於返回元組或者列表形式。
str = '1234' print(list(str)) #['1', '2', '3', '4'] print(tuple(str)) #('1', '2', '3', '4') str2 = ('12','dd') print(list(str2)) #['12', 'dd']
9. 引用
(1)Python 中關於引用的知識點同 C 語言中十分類似,C 語言中如:int a = 3,實際上 a 形參是通過地址找到存儲 3 整個數字的 “格子
而數組 a[1,2,3] 則直接。這和 Python 幾乎一致。所以在 Python 中,普通類型的復制如 b = a 復制值,而數組之間復制,復制的是引用(即地址)。同樣,如果在傳遞給函數時,傳遞的參數是數組,則會改變原數組,傳遞的是一般數據類型,則不會修改原值,如:
def test(str): str += 'g' def test2(name): del name[0] str = 'ddd' test(str) print(str) #ddd 未修改 name = [1,2,3] test2(name) print(name) #[2, 3] #[2, 3] 修改
(2)在處理列表時,傳入的是引用,如果只想傳入值,即修改了數組而不影響原有函數,通過 copy() 實現。如果要復制的列表中還包含列表,使用 deepcopy() 。
1 import copy 2 3 name = [1,2,3,[1,2,3]] 4 5 a = name 6 b = copy.copy(name) 7 c = copy.deepcopy(name) 8 9 a.append('aaa') 10 print(name) #[1, 2, 3, [1, 2, 3], 'aaa'] 說明對name原列表有效,a列表改變name列表也改變了 11 12 b.append('bbb') 13 print(name) #[1, 2, 3, [1, 2, 3], 'aaa'] 說明name原對列表有效 14 15 b[3].append('444') 16 print(name) #[1, 2, 3, [1, 2, 3, '444'], 'aaa'] 說明原列表有效 17 18 c.append('555') 19 print(name) #[1, 2, 3, [1, 2, 3, '444'], 'aaa'] 說明無效
10. 字典 dict
(1)字典即 Map
由鍵值對組成。字典不同於列表,字典中表項是不排序的,如(字典不能排序)
t = [1,2,3] e = [2,1,3] print(t == e) #False g = {'k':'j', 'kk':'jj'} h = {'kk':'jj', 'k':'j'} print(g == h) #True
print('k' in g) #True 判斷 key 是否存在
(2)keys() 方法,values() 方法,items() 方法
g = {'k':'j', 'kk':'jj'} for v in g.keys(): #key print(v) for t in g.values(): #value print(t) for b in g.items(): #key-value print(b) #輸出元組
print(list(b)) #輸出列表
for v,t in g.items(): #多重賦值
print('Key:',v,"Value",t)
(3)get() 方法
如果通過 key 值取值,存在 key 不存在的風險,get() 函數可以設置一個默認返回值,避免錯誤。
g = {'name':'Tom', 'age':'12'} print('Welcom', g.get('name', 'Jack'), 'he lives in', g.get('home','shanghai')) #Jack 和 shanghai就是如果get不到值就,默認返回值
(4)setdefault() 方法
該方法可以設置默認 key 對應的 value。如果該 key 已經存在,則無效,如:
g = {'r':'rr','b':'bb'} g.setdefault('k', 'kk') print(g) #{'r': 'rr', 'b': 'bb', 'k': 'kk'} 修改有效 g.setdefault('k','mm') print(g) #{'r': 'rr', 'b': 'bb', 'k': 'kk'} 修改無效
有一個較實用的場景,統計字符:
msg = 'fadfasfasdfadsfs' count = {} for v in msg: count.setdefault(v, 0) #很關鍵 設置為0,而不是1 count[v] += 1 print(count)
11.正則表達式
(1)①引入 re 模塊。②按要求創建 regex 對象。③通過 regex 對象查找
import re #① phoneNumRegex = re.compile(r'\d\d\d-\d\d\d-\d\d\d\d') #② \d 表示數字。此處查找目標格式如下行的電話號碼。 mo = phoneNumRegex.search('My phone number is 123-123-1234') #③------------不過 search 只能匹配第一個符合的字符串。使用 findall 可以匹配到所有 if mo != None: print(mo.group())
(2)利用括號進行分組
即在上一步基礎上 r '(\d\d\d)-(\d\d\d)-(\d\d\d\d)' 添加括號,第一組括號就是第一組...,這樣的目的是可以在獲得整個電話號碼的基礎上,再細致的得到前三位,中間三位活末四位。
import re #① phoneNumRegex = re.compile(r'(\d\d\d)-(\d\d\d)-(\d\d\d\d)') #② mo = phoneNumRegex.search('My phone number is 111-222-3333') #③ if mo != None: print(mo.group()) # 111-222-3333。或者用 mo.group(0) print(mo.group(3)) #3333,第三組括號 print(mo.groups()) #可獲得全部分組 ('111', '222', '3333') arg1, arg2, arg3 = mo.groups() #用賦值 v1, v2 = mo.group(1), mo.group(0) print(arg1, arg2, arg3, v1, v2)
(3)管道
①通過字符 ‘|’ 來匹配多個表達式中一個,類似 or 的作用。
import re match = re.compile(r'Batman|Ironman') #匹配Batman 或者Ironman 字符 mo = match.search('Hi Ironman ABatman and CC Ironman') print(mo.group())
②也可以使用管道來匹配多個模式中的一個,如需要找112,113,114,前綴11均相同。
import re match = re.compile(r'11(2|3|4)') #匹配112、113、114 mo = match.search('Hi 114 22811210114') print(mo.group(), mo.group(1)) #114 4。前者輸出完全匹配的完整內容,后者輸出括號內匹配的文本4。
(4)用問號 ?實現可選匹配
import re match = re.compile(r'11(2|3|4)?xx') #匹配112xx、113xx、114xx mo = match.search('Hi 114xx') print(mo.group()) #114xx mo = match.search('Hi 11xx') print(mo.group()) #11xx。因為(2|3|4)?表示這三個數字是可選內容。
(5)用星號匹配零次或任意多次。如果需要匹配星號,則通過添加斜杠完成
import re match = re.compile(r'11(2|3|4|\*)*xx') mo = match.search('Hi 114222*xx') print(mo.group()) #114222*xx mo = match.search('Hi 11xx') print(mo.group()) #11xx
(6)用加號,則表示至少一次或者多次。與星號類似
import re match = re.compile(r'11(2|3|4|\*\+)+xx') mo = match.search('Hi 114222*+xx') print(mo.group()) #114222*+xx mo = match.search('Hi 11xx') if mo == None: print('沒有匹配到') #沒有匹配到
(7)通過添加花括號來限定匹配的次數
import re e = re.compile(r'(11){2}') #{2}表示2次,{,2}表示0~2次,{2,}至少兩次,{2,3}兩次或者三次 mo = e.search('11231111232') print(mo.group()) #1111
還要注意一點,Python 默認是貪心策。如 (11){2,4},輸入11111111,輸出的是 11111111,而不是1111。但是如果(11){2,4}?則輸出的是1111。問號的作用:①聲明非貪心策略②表示可選分組。
(8)findall() 方法
search() 方法只能返回一個 match 對象。①如果在正則表達式中沒有分組,則返回的是一個列表 ②有分組,則返回的是一個元組。如
import re e = re.compile(r'(11){1}\d') print(e.search('11231111432').group()) #112。只能找到第一次出現且符合要求的 print(e.findall('11231111432')) #['11', '11']。因為有分組即有括號,所以只能輸出分組內容“(11)”,不能輸出符合要求的112和114。此處分組為11 e2 = re.compile(r'1111\d') print(e2.findall('1111231111232')) #['11112', '11112']。沒有分組,這是最理想最期待看到的結果 e3 = re.compile(r'(11){2}\d') print(e3.findall('1111231111232')) #['11', '11']。(11){2},即此處分組為 11,括號即分組 e4 = re.compile(r'(\d\d\d)-(\d\d\d)-(\d\d\d\d)') print(e4.findall('cell 123-456-7890 work: 111-222-3333')) #[('123', '456', '7890'), ('111', '222', '3333')]
(9)字符的分類
- \d 0~9 任意數字
- \D 除了 0~9 之外任意數字
- \w 字母,數字,下划線
- \W 除......
- \s 匹配空白
- \S 除......
(10)建立自己的字符分類
- 用方括號定義自己的字符分類,如,[aeiou]
- 用短橫線表示字母或者數組的范圍,如,[0-1a-zA-Z]。注意:普通正則表達式符號在方括號內不會被解釋,不需要加 \ 進行轉義
- ^ 表示非。[ ^aeiou ],正好和第一條相反。在字符左方括號后加。
(11)插入字符和美元字符
可以在正則表達式開始處使用插入符號 ^ ,表明匹配必須發生在被查找文本開始處。類似的,可以在正則表達式末尾加上 $ ,表示該字符串必須以這個正則表達式模式結束。
import re begin = re.compile(r'^hello') print(begin.search('hello').group()) end = re.compile(r'\d$') print(end.search('da233').group()) a = re.compile(r'^\d+$') #從頭到尾是數字。加號關鍵,表示個數不限制 print(a.search('121t4')) #None print(a.search('12164').group()) #12164
(12)通配符
“ .” (句號) 是通配符,匹配除了換行之外的所有字符,但是只匹配一位。要匹配真正的句號,需要用轉義符:\ . 。
(13)用點-星匹配除換行符之外所有字符
點可以匹配除了換行符之外的所有字符,星表示前面的字符出現0次或多次。
import re test = re.compile(r'<.*?>') mo = test.search('<To serve man> for dinner.>') print(mo.group()) test2 = re.compile(r'<.*>') #去掉問號,默認貪心策略 mo = test2.search('<To serve man> for dinner.>') print(mo.group())
通過傳入參數:re.DOTALL 來做到匹配換行符:
import re test2 = re.compile('.*') mo = test2.search('<To serve man>\n for dinner.>') print(mo.group()) #<To serve man> test3 = re.compile('.*', re.DOTALL) mo = test3.search(r'<To serve man>\n for dinner.>') print(mo.group()) #<To serve man>\n for dinner.>
(點擊圖片查看原文)
(14)不區分大小寫的匹配
通過傳入參數:re.IGNORECASE 或 re.I 。
import re t = re.compile('aaBB', re.I) print(t.search('AAbbdd').group()) #AAbb
(15)用 sub() 方法替換字符串
即找到目標文字段,並替換,返回替換之后的字符串 。
import re t = re.compile('Alice \w+') #表示Alice+空格+一個單詞(\w => 字母數字下划線) print(t.sub('替換掉', 'Alice hello Pattern')) #替換掉 Pattern
有時候,可能需要使用匹配文本本身,作為替換的一部分。在 sub() 的第一個參數中,可以輸入 \1, \2, \3.....。表示 “ 在替換中輸入分組1、2、3..... 的文本”。(-----《Python編程快速上手》)
如,假定想要隱去密探的姓名,只顯示他們姓名的第一個字母。可以使用正則表達式 Agent(\w)\w* ,傳入 r ' \1**** ' 作為 sub() 的第一個參數。字符串中的 \1 將由分組 1 匹配的文本所替代,也就是正則表達式的(\w)分組。
import re agentName = re.compile(r'Agent (\w)\w*') #寫成 (\w)\w* 的形式完全為了取得首字母,若名字全部*代替,則直接 \w* str = 'Agent Alice told Agent that Agent Jack knew Agent Bob was a double agent' print(agentName.sub(r'\1****', str)) #A**** told t**** J**** knew B**** was a double agent agentName = re.compile(r'Agent (\w)\w*(\w)') print(agentName.sub(r'\1**\2', str)) #A**e told t**t J**k knew B**b was a double agent
(16)一個簡單的應用
#電話號碼/E-mail提取 import re phoneNumb = re.compile(r''' (\d{3}|\(d{3}\))? #①注意(需要轉義符 ②表示:數字三個或者被括號包圍的數字三個或者不存在--問號的意義 (\s|-\.)? #號碼可通過空格,短線,或者"."--此處表示真正意義上的點,所以需要轉義符。問號(表示0次或1次)和句點在正則表達式中均有特殊意義,所以需要轉義符 (\d{3}) (\s|-\.) (\d{4}) #形如(111)-223-4444 ''') email = re.compile(r''' [a-zA-Z0-9.%+-]+ #Email 用戶名可以是一個或多個字母/數字/./%/+/- @ [a-zA-Z0-9.-]+ #域名 ''')
(17)幾個例子
①匹配隔至多三個數字之后必須要有一個逗號,如【42】【1,234】【6,222,111】---------------------------- r ’ ^ \d {1,3} (,\d{3}) * $ ‘ 。有點循環的味道
12. 讀寫文件
(1)① Windows 下的倒斜杠和 OS X 下的正斜杠。前者是 / ,后者是 \。可以通過 os.path.join() 函數返回在 OS X 下目錄格式。 ② os.getcwd() 得到當前工作目錄。 ③ “ . (句點)” 表示當前目錄。os.path.abspath() 將返回參數的絕對路徑字符串。os.path.isabs() 將判斷是否為絕對路徑。os.path.relpath(path, start) 將返回path 相對於 start 的相對路徑,start 默認是當前路徑。
import os print(os.path.join('usr', 'bin', 'spam')) #usr\bin\spam print(os.getcwd()) #F:\Python print(os.path.abspath('..')) #F:\ print(os.path.isabs('F:\\')) #True 錯誤寫法:(r'F:\') print(os.path.relpath('F:\\')) #..
print(os.path.relpath('F:\Python', 'F:\\')) #Python (path, start)
(2)os.makedirs() 創建新文件夾。 os.path.dirname(path) 返回最后一個斜杠之前的所有內容,os.path.basename(path) 返回最后一個斜杠之后的內容。 os.path.split() 返回一個元組正好是前兩者的內容。如果想通過 \ 對路徑進行分割,可以通過字符串的 split() 的分割方法。
import os str = 'F:\\test\\test2' #os.makedirs(str) #創建了F:\test\test2 print(os.path.dirname(str)) #F:\test print(os.path.basename(str)) #test2 print(os.path.split(str)) #('F:\\test', 'test2') 輸出以上兩條合並的元組 print(os.path.sep) # \ 反斜杠 print(str.split(os.path.sep)) # ['F:', 'test', 'test2']。或者str.split('\\')
(3)查看文件大小和內容。os.listdir(path) , os.path.getsize(path)。
import os print(os.path.getsize('F:\\Python\\Hello.py')) #得到文件大小 print(os.listdir('F:\\Python')) #得到整個目錄 totalsize = 0 for file in os.listdir('F:\\Python'): #totalsize += os.path.getsize('F:\\Python\\' + file) #集算整個目下文件字節數。寫法二 totalsize += os.path.getsize(os.path.join('F:\\Python', file)) print(totalsize)
(4)檢查路徑的有效性。os.path.exists(path) 判斷路徑是否正確。os.path.isfile(path) 判斷是否為文件。os.path.isdir(path) 是否是目錄。
import os str = 'F:\\Python\\Hello.py' print(os.path.exists(str), os.path.isdir(str), os.path.isfile(str))
(5)Python 讀取文件一樣是 Open()、Read()、Close() 等基本步驟。
#讀文件
import os if os.path.isfile(".\\t.py") == True: testFile = open(".\\t.py", encoding='UTF-8') #被讀內容含中文。具體有待深究。先插眼 #content = testFile.read() #還方法將文件內容看成是單個大字符串。法一 content = testFile.readlines() #從該文件取得一個字符串列表,列表中的每個字符串就是文本的每一行。 print(content)
#讀寫文件 import os if os.path.isfile(".\\t.py") == True: testFile = open(".\\t.py", 'a', encoding='UTF-8') #傳入參數 w 寫模式,a 添加模式。如果文件不存在,這兩種模式會創建新文件 testFile.write('寫入測試\n') testFile.close() #寫入完成之后必須關閉 testFile = open('.\\t.py', 'r', encoding='UTF-8') #重新打開,為了再次讀 print(testFile.read())
(6)用 shelve 模塊保存變量。主要功能是可以將一些變量存儲在硬盤上,下次運行時直接加載它們。
import shelve shelveFile = shelve.open('.\\data') #在當前目錄創建。會產生三個文件 data.bak,data.dat,data.dir cats = ['zo', 'to', 'po'] shelveFile['yo'] = cats #可以將 shelvesFile 看成key-value形式的Map shelveFile.close()
import shelve shelveFile = shelve.open('.\\data') print(shelveFile['yo']) #['zo', 'to', 'po'] shelveFile.close()