Python基礎(一)


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()

 


免責聲明!

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



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