Python之路【第八篇】:Python模塊

閱讀目錄

1、模塊和包

模塊(module)的概念:node

在計算機程序的開發過程當中,隨着程序代碼越寫越多,在一個文件裏代碼會愈來愈長,愈來愈不容易維護。python

爲了編寫可維護的代碼,咱們把不少函數分組,分別放到不一樣的文件裏,這樣,每一個文件包含的代碼就相對較少,不少編程語言都採用這種組織代碼的方式。在Python中,一個.py文件就稱之爲一個模塊(module)。linux

使用模塊有哪些好處?web

1、最大的好處就是大大提升了代碼的可維護性。
二、編寫代碼沒必要從零開始。當一個模塊編寫完成,就能夠被其餘地方調用。咱們在編寫程序的時候,也常常飲用其餘模塊,包括Python內置的模塊和來自第三方的模塊。

模塊一共分爲三種:正則表達式

一、python標準庫
二、第三方模塊
三、應用程序自定義模塊

注意:shell

使用模塊還能夠避免函數名跟變量名衝突。相同名字的函數和變量徹底能夠分別存在不一樣的模塊中,所以,咱們在本身編寫模塊時,沒必要考慮名字會與其餘模塊衝突。可是也要注意,儘可能不要與內置函數名字衝突。django

2、模塊的導入方法

一、import語句

import module1,[module2[,...moduleN]]

當咱們使用import語句的時候,Python解釋器是怎樣找到對應的文件?答案就是解釋器有本身的搜索路徑,存在sys.path裏。編程

import sys
print(sys.path) 運行結果以下: ['G:\\python_s3\\day21', 'G:\\python_s3', 'C:\\Python35\\python35.zip', 'C:\\Python35\\DLLs', 'C:\\Python35\\lib', 'C:\\Python35', 'C:\\Python35\\lib\\site-packages', 'D:\\Program Files (x64)\\pycharm軟件安裝\\config\\PyCharm 2018.3\\helpers\\pycharm_matplotlib_backend']

所以若像我同樣在當前目錄下存在與要引入模塊同名的文件,就會把要引入的模塊沒屏蔽掉。json

二、from...import ...語句

from modname import name1[,name2[, ... nameN]]

這個聲明不會把整個modulename模塊導入到當前的命名空間中,只會講它裏面的name1或name2單個引入到執行這個聲明的模塊的全局符號表。 windows

三、from...import*語句

from modname import *

四、運行本質

一、import test
二、from test import add

不管1仍是2,首先經過sys.path找到test.py,而後執行test腳本,區別是1會將test這個變量名加載到名字空間,而2只會將add這個變量名加載進來。

五、包(package)

1、若是不一樣的人編寫的模塊名相同怎麼辦?爲了不模塊名衝突,Python又引入了按目錄來組織模塊的方法,成爲包(Package)。
舉個例子:一個abc.py的文件就是一個名字叫abc的模塊,一個simon.py的文件就是一個叫simon的模塊。
如今,假設咱們的abc和simon這兩個模塊名字和其餘模塊起衝突了,因而咱們能夠經過包來組織模塊,從而避免衝突。方法就是選擇一個頂層包名:


2、引入了包之後,只要頂層的包名不與別人衝突,那全部模塊都不會與別人衝突。如今,view.py模塊的名字就變成了hello_django.app01.views,相似的,manage.py的模塊名則是hello_django.manage。 請注意,每個包目錄下面都會有一個__init__.py的文件,這個文件是必須存在的,不然,Python就把這個目錄當成普通目錄(文件夾),而不是一個包。__init__.py能夠是空文件,也能夠有Python代碼,由於__init__.py自己就是一個模塊,而它的模塊名就是對應包的名字。

注意點(important)

調用包就是執行包下的__init__.py文件

#1--------------------------------
在node1中import hello是找不到的,有人說能夠找到呀,那是由於你的pycharm爲你把myapp這一層路徑加入到了sys.path裏面,因此能夠找到,然而程序一旦在命令行運行,則報錯。有同窗問那怎麼辦?簡單啊,本身把這個路徑加進去不就OK啦:


import sys,os BASE_DIR=os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.append(BASE_DIR) #臨時修改 import hello hello.hello1()
#二、--------------
if __name__=='__main__':
    print('ok')

「Make a .py both importable and executable」

若是咱們是直接執行某個.py文件的時候,該文件中那麼"__name__ == '__main__' "是True,可是咱們若是從另一個.py文件經過import導入該文件的時候,這時__name__的值就是咱們這個py文件的名字而不是__main__.

這個功能還有一個用處:調試代碼的時候,在"if __name__ == '__main__' "中加入一些咱們的調試代碼,咱們可讓外部模塊調用的時候不執行咱們的調試代碼,可是若是咱們想排查問題的時候,直接執行該模塊文件,調試代碼可以正常運行!

##-------------cal.py
def add(x,y):
 
    return x+y ##-------------main.py import cal #from module import cal def main(): cal.add(1,2) ##--------------bin.py from module import main main.main()

注意:

 

# from module import cal 改爲 from . import cal一樣能夠,這是由於bin.py是咱們的執行腳本,
# sys.path裏有bin.py的當前環境。即/Users/simon/Desktop/whaterver/project/web這層路徑,
# 不管import what ,  解釋器都會按這個路徑找。因此當執行到main.py時,import cal會找不到,由於
# sys.path裏沒有/Users/simon/Desktop/whaterver/project/web/module這個路徑,而
#  from  module/.  import cal 時,解釋器就能夠找到了。

3、time模塊(* * * *)

三種時間表示

在Python中,一般有這幾種方式來表達時間:
一、時間戳(timestamp):一般來講,時間戳表示的是從1970年1月1日00:00:00開始按秒計算的偏移量。咱們運行「type(time.time())」,返回的是float類型。 2、格式化的時間字符串 三、元祖(struct_time):struct_time元祖共有9個元素:(年,月,日,時,分,秒,一年中第幾周,一年中第幾天,夏令時)
import time

#一、time():  返回當前時間的時間戳
print(time.time()) 運行結果以下: C:\Python35\python3.exe G:/python_s3/day21/example.py 1555996405.5020845 #二、localtime(secs): 將一個時間戳轉換爲當前時區的struct_time。secs參數未提供,則以當前時間爲準。 print(time.localtime()) 運行結果以下: C:\Python35\python3.exe G:/python_s3/day21/example.py time.struct_time(tm_year=2019, tm_mon=4, tm_mday=23, tm_hour=13, tm_min=18, tm_sec=9, tm_wday=1, tm_yday=113, tm_isdst=0) #三、gmtime([secs])和localtime()方法相似,gmtime()方法是將一個時間戳轉換爲UTC時區(0時區)的struct_time。 print(time.gmtime()) 運行結果以下: C:\Python35\python3.exe G:/python_s3/day21/example.py time.struct_time(tm_year=2019, tm_mon=4, tm_mday=23, tm_hour=5, tm_min=21, tm_sec=25, tm_wday=1, tm_yday=113, tm_isdst=0) #四、mktime(t): 將一個struct_time轉化爲時間戳 print(time.mktime(time.localtime())) #  運行結果以下: C:\Python35\python3.exe G:/python_s3/day21/example.py 1555998160.0 #五、asctime([t]): 把一個表示時間的元祖或者struct_time表示爲這種形式:'Tue Apr 23 13:45:49 2019' #若是沒有參數,將會將time.localtime()做爲參數傳入。 print(time.asctime()) 運行結果以下: C:\Python35\python3.exe G:/python_s3/day21/example.py Tue Apr 23 13:45:49 2019 #六、ctime([secs]): 把一個時間戳(按秒計算的浮點數)轉化爲time.asctime()的形式。若是參數未給或者爲None的時候,將會默認time.time()爲參數。它的做用至關於time.asctime(time.localtime(secs))。 print(time.ctime()) #Tue Apr 23 14:02:45 2019 print(time.ctime(time.time())) #Tue Apr 23 14:03:50 2019 #七、strftime(format[,t]) #把一個表明時間的元祖或者struct_time(如由time.localtime()和time.gmtime()返回) 轉化爲格式化的時間字符串。若是t未指定,將傳入time.localtime()。若是元組中任何一個元素過界,ValueError的錯誤將會被拋出。 print(time.strftime("%Y-%m-%d %X",time.localtime())) #2019-04-23 14:11:12 #八、time.strptime(string[, format]) #把一個格式化時間字符串轉化爲struct_time。實際上它和strftime()是逆操做。 print(time.strptime('2019-04-23 14:15:07', '%Y-%m-%d %X')) 輸出結果爲: time.struct_time(tm_year=2019, tm_mon=4, tm_mday=23, tm_hour=14, tm_min=15, tm_sec=7, tm_wday=1, tm_yday=113, tm_isdst=-1) #在這個函數中,format默認爲:"%a %b %d %H:%M:%S %Y"。 #九、sleep(sesc) print(time.sleep(3)) #線程推遲指定的時間運行,單位爲秒。 #十、clock # 這個須要注意,在不一樣的系統上含義不一樣。在UNIX系統上,它返回的是"進程時間",它是用秒錶示的浮點數(時間戳)。而在windows中,第一次調用,返回的是進程運行的實際時間。而第二次以後的調用是自第一次調用之後到如今的運行時間,即兩次時間差。

關係圖:

4、random模塊(* *)

import random

ret=random.random() # ret=random.randint(1,3) #[1,3] # ret=random.randrange(1,3) #[1,3] # ret=random.choice([11,22,33,44,55]) # ret=random.sample([11,22,33,44,55],2) # ret=random.uniform(1,4) # print(ret) # ret=[1,2,3,4,5] # random.shuffle(ret) # print(ret)  item=[1,3,5,7,9] random.shuffle(item) print(item)

#隨機生成驗證碼

import random
def v_code(): ret="" for i in range(5): num=random.randint(0,9) alf=chr(random.randint(65,122)) s=str(random.choice([num,alf])) ret+=s return ret print(v_code())

5、os模塊(* * * *)

os模塊是與操做系統交互的接口

os.getcwd()  #獲取當前工做目錄,即當前python腳本的目錄路徑

os.chdir("dirname")  #改變當前腳本工做目錄,至關於shell下cd
 os.cudir #返回當前目錄:(' . ')  os.pardir #獲取當前目錄的父目錄字符串名:(' . . ')  os.makedirs('dirname1/dirname2') #可生成多層遞歸目錄  os.removedirs('dirname1') #若目錄爲空,則刪除,並遞歸到上一級目錄,如若也爲空,則刪除,依此類推  os.mkdir('dirname') #生成單級目錄,至關於linux中mkdir dirname  os.rmdir('dirname') #刪除單級空目錄,若目錄不爲空則沒法刪除,報錯,至關於shell中rmdir dirname  os.listdir('dirname') #列出指定目錄下的全部文件和子目錄,包含隱藏文件,並以列表的方式打印  os.remove() #刪除一個文件  os.rename("oldname","newname") #重命名文件/目錄  os.stat('path/filename') #獲取文件/目錄信息 例: print(os.stat("sss.py")) C:\Python35\python3.exe G:/python_s3/day22/os_test.py os.stat_result(st_mode=33206, st_ino=11821949021847676, st_dev=2159804260, st_nlink=1, st_uid=0, st_gid=0, st_size=10, st_atime=1556025329, st_mtime=1556025329, st_ctime=1556025302) os.sep #輸出操做系統特定的路徑分隔符,win下爲"\\",Linux下爲"/"  os.linesep #輸出當前平臺使用的行終止符,win下爲"\r\n",Linux下爲"\n"  os.pathsep #輸出用於分隔文件路徑的字符 win下爲; ,Linux下爲:  os.name #輸出字符串指示當前使用平臺。win-->'nt'; Linux-->'posix'  os.system("bash command") #運行shell命令,直接顯示  os.environ #獲取系統環境變量 例: print(os.environ) environ({'FP_NO_HOST_CHECK': 'NO', 'PUBLIC': 'C:\\Users\\Public', 'PYCHARM': 'D:\\Program Files (x64)\\pycharm軟件安裝\\config\\PyCharm 2018.3\\bin;', 'COMPUTERNAME': 'DELL-PC', 'PYTHONPATH': 'G:\\python_s3;D:\\Program Files (x64)\\pycharm軟件安裝\\config\\PyCharm 2018.3\\helpers\\pycharm_matplotlib_backend', 'PYCHARM_HOSTED': '1', 'PYCHARM_MATPLOTLIB_PORT' os.path.abspath(path) #返回path規範化的絕對路徑  os.path.split(path) #將path分割成目錄和文件名二元組返回 例: print(os.path.split(r"G:\python_s3\day22\sss.py")) 輸出結果: ('G:\\python_s3\\day22', 'sss.py') os.path.dirname(path) #返回path的目錄。其實就是os.path.split(path)的第一個元素 例: print(os.path.dirname(r"G:\python_s3\day22\sss.py")) 輸出結果: G:\python_s3\day22 os.path.basename(path) #返回path最後的文件名,若是path以/ 或 \結尾,那麼就會返回空值。即os.path.split(path) 的第二個元素 例: print(os.path.basename(r"G:\python_s3\day22\sss.py")) 輸出結果: sss.py os.path.exists(path) #若是path存在,返回True;若是path不存在,返回False  os.path.isabs(path) #若是path是絕對路徑,返回True  os.path.isfile(path) #若是path是一個存在的文件,返回True,不然返回False  os.path.isdir(path) #若是path是一個存在的目錄,則返回True,不然返回False  os.path.join(path1,paht2[, ...]) #將多個路徑組合後返回,第一個絕對路徑以前的參數將被忽略 例: a="G:\python_s3\day22" b="sss.py" print(os.path.join(a,b)) 輸出結果: G:\python_s3\day22\sss.py os.path.getatime(paht) #返回path所指向的文件或者目錄的最後存取時間  os.path.getmtime(path) #返回path所指向的文件或者目錄的最後修改時間

6、sys模塊(* * *)

#一、sys.argv            命令行參數List,第一個元素是程序自己路徑
#二、sys.exit(n)         退出程序,正常退出時exit(0)
#三、sys.version        獲取Python解釋程序的版本信息
#四、sys.maxint         最大的Int值
#五、sys.path            返回模塊的搜索路徑,初始化時使用PYTHONPATH環境變量的值
#六、sys.platform       返回操做系統平臺名稱
#七、sys.stdout.write("please:") #標準輸出,引出進度條的例子,注意,在py3上不行,能夠用print代替
#八、sys.stdout.flush() #刷新緩存
##進度條
import time,sys
for i in range(10): sys.stdout.write('#') time.sleep(1) sys.stdout.flush() 輸出結果: C:\Python35\python3.exe G:/python_s3/day22/sys_test.py ##########

7、json&pickle模塊(* * * *)

以前咱們學習過用eval內置方法能夠將一個字符串轉成python對象,不過,eval方法是有侷限性的,對於普通的數據類型,json.loads和eval都能用,但遇到特殊類型的時候,eval就無論用了,因此eval的重點仍是一般用來執行一個字符串表達式,並返回表達式的值。

 用於序列化的兩個模塊

● json,用於任何語言 和 python數據類型間進行轉換

● pickle,用於python特有的類型 和 python的數據類型間進行轉換

dic='{"name":"simon"}'
f=open('hello','w') f.write(dic) f_read=open('hello','r') data=f_read.read() print(type(data)) #讀到的文件內容是字符串<class 'str'> data=eval(data) #將字符串轉成字典 print(data['name']) #讀取字典name對應的值  輸出結果爲: C:\Python35\python3.exe G:/python_s3/day22/json&pickle.py <class 'str'> simon

一、什麼是序列化?

咱們把對象(變量)從內存中變成可儲存或傳輸的過程稱之爲序列化,在Python中叫pickling,在其餘語言中也稱之爲serialization,marshalling,flattening等。

序列化以後,就能夠把序列化後的內容寫到磁盤,或者經過網絡傳輸到別的機器上。

反過來,把變量內容從序列化的對象從新讀到內存裏稱之爲反序列化,即unpicking。

二、json

若是咱們要在不一樣的編程語言之間傳遞對象,就必須把對象序列化爲標準格式,好比XML,但更好的方法是序列化爲JSON,由於JSON表示出來就是一個字符串,能夠被全部語言讀取,也能夠方便的存儲到磁盤或者經過網絡傳輸。JSON不只是標準格式,而且比XML更快,並且能夠直接在Web頁面中讀取,很是方便。

JSON表示的對象就是標準的JavaScript語言的對象,JSON和Python內置的數據類型對應以下:

JSON類型 Python類型
{} dict
[] list
"string" str
1234.56 int或float
true/false True/False
null None
#一、經過eval處理,只能講字符串轉成字典
dic='{"name":"simon"}'
# f=open('hello','w')
# f.write(dic)

f=open('hello','r') data=f.read() print(type(data)) #讀到的文件內容是字符串<class 'str'> data=eval(data) ##將字符串轉成字典 print(data["name"]) #讀取字典name對應的值  打印: <class 'str'> simon
#二、經過json模塊處理python字典
import json
dic={"name":"simon"}   #----------->{"name":"simon"}-------'{"name":"simon"}'
 dic_str=json.dumps(dic) print(dic_str) #{"name": "simon"} print(type(dic_str)) #<class 'str'> f=json.loads(dic_str) #將json字符串經過loads轉成字典的過程 print(f) #{'name': 'simon'} print(type(f)) #<class 'dict'> print(f["name"]) #simon  打印: {"name": "simon"} <class 'str'> {'name': 'simon'} <class 'dict'> simon
#二、經過json模塊處理python數字
i=8    
i=json.dumps(i)  #不管是字典、字符串、列表、整型,json.dumps都會把不管是單引號仍是雙引號多會轉成雙引號,而後加單引號變成json字符串
print(i) p=json.loads(i) print(type(p)) 打印: 8 <class 'str'> <class 'int'>
#三、經過json模塊處理字符串
s='hello'              #----------->"hello"----------->'"hello"',json.dumps都會把不管是單引號仍是雙引號都會轉成雙引號,而後加單引號變成json字符串
s=json.dumps(s)
print(s) p=json.loads(s) #經過json.loads將dumps後的json字符串轉爲json支持的數據類型 print(p) print(type(p)) 打印: "hello" hello <class 'str'>
#四、經過json模塊處理列表
l=[1,2,3]              #----------->"[1,2,3]"
l=json.dumps(l)
print(l) print(type(l)) p=json.loads(l) print(p) #轉成json的列表類型 print(type(p)) 打印: [1, 2, 3] <class 'str'> [1, 2, 3] #處理後的json列表 <class 'list'>
#五、對於文件的操做dumps方法能夠用dump替代
f_read=open("new_hello","r")
data=json.loads(f_read.read())   #等價於data=json.load(f_read)
print(data) print(type(data)) print(data["name"])
#注意點:
import json
#dct="{'1':111}"#json 不認單引號
#dct=str({"1":111})#報錯,由於生成的數據仍是單引號:{'one': 1}

dct='{"1":"111"}'
print(json.loads(dct))

#conclusion:
#        不管數據是怎樣建立的,只要知足json格式,就能夠json.loads出來,不必定非要dumps的數據才能loads

注意點

三、pickle

#--------------------pickle------------------
import pickle

dic={'name':'william','age':24,'sex':'male'} print(type(dic)) #<class 'dict'>  j=pickle.dumps(dic) print(type(j)) #<class 'bytes'>  f = open('序列化對象_pickle','wb') #注意是w是寫入str,wb是寫入bytes,j是'bytes' f.write(j) #------------------------等價於pickle.dump(dic,f) # pickle.dump(dic,f) f.close() #----------------------------反序列化  f = open('序列化對象_pickle','rb') data = pickle.loads(f.read()) #等價於data=pickle.load(f) print(data['age']) #24

pickle的問題和全部其餘編程語言特有的序列化問題同樣,就是它只能用於Python,而且不一樣於其餘版本的python彼此版本不兼容,所以,只能用pickle保存那些不重要的數據,不能成功地反序列化也不要緊。

8、shelve模塊(* * *)

import shelve

f = shelve.open(r'shelve')  #目的:將一個字典放入文本 f={}

# f['stu1_info']={'name':'simon','age':'18'}
# f['stu2_info']={'name':'simonn','age':'20'}
# f['school_info']={'website':'baidu.com','city':'beijing'}
#
#
# f.close()

print(f.get('stu1_info')['age'])   #18

9、xml模塊(* * *)

xml是實現不一樣語言或程序之間進行數據交換的協議,跟json差很少,但json使用起來更簡單,不過,古時候,在json還沒誕生的黑暗年代,你們只能選擇用xml呀,至今不少傳統公司如金融行業的不少系統的接口還主要是xml。

xml的格式以下,就是經過<>節點來區別數據結構的:

<?xml version="1.0"?>
<data>
    <country name="Liechtenstein">
        <rank updated="yes">2</rank>
        <year>2008</year>
        <gdppc>141100</gdppc>
        <neighbor name="Austria" direction="E"/>
        <neighbor name="Switzerland" direction="W"/>
    </country>
    <country name="Singapore">
        <rank updated="yes">5</rank>
        <year>2011</year>
        <gdppc>59900</gdppc>
        <neighbor name="Malaysia" direction="N"/>
    </country>
    <country name="Panama">
        <rank updated="yes">69</rank>
        <year>2011</year>
        <gdppc>13600</gdppc>
        <neighbor name="Costa Rica" direction="W"/>
        <neighbor name="Colombia" direction="E"/>
    </country>
</data>

xml數據

xml協議在各個語言裏的都 是支持的,在python中能夠用如下模塊操做xml:

import xml.etree.ElementTree as ET
 
tree = ET.parse("xmltest.xml") root = tree.getroot() print(root.tag) #遍歷xml文檔 for child in root: print(child.tag, child.attrib) for i in child: print(i.tag,i.text) #只遍歷year 節點 for node in root.iter('year'): print(node.tag,node.text) #--------------------------------------- import xml.etree.ElementTree as ET tree = ET.parse("xmltest.xml") root = tree.getroot() #修改 for node in root.iter('year'): new_year = int(node.text) + 1 node.text = str(new_year) node.set("updated","yes") tree.write("xmltest.xml") #刪除node for country in root.findall('country'): rank = int(country.find('rank').text) if rank > 50: root.remove(country) tree.write('output.xml')

本身建立xml文檔:

import xml.etree.ElementTree as ET
 
 
new_xml = ET.Element("namelist") name = ET.SubElement(new_xml,"name",attrib={"enrolled":"yes"}) age = ET.SubElement(name,"age",attrib={"checked":"no"}) sex = ET.SubElement(name,"sex") sex.text = '33' name2 = ET.SubElement(new_xml,"name",attrib={"enrolled":"no"}) age = ET.SubElement(name2,"age") age.text = '19' et = ET.ElementTree(new_xml) #生成文檔對象 et.write("test.xml", encoding="utf-8",xml_declaration=True) ET.dump(new_xml) #打印生成的格式

10、re模塊(* * * * *)

一、什麼是正則?

正則就是用一些具備特殊含義的符號組合到一塊兒(稱爲正則表達式)來描述字符或者字符串的方法。或者說:正則就是用來描述一類事物的規則。(在python中)它內嵌在Python中,並經過re模塊實現。正則表達式模式被編譯成一系列的字節碼,而後由用C編寫的匹配引擎執行。

 字符匹配(普通字符,元字符):

一、普通字符:大多數字符和字母都會和自身匹配

>>> re.findall("zhurui","FREWRFVZHURzhuruiSIMONsimon")
['zhurui']
>>>

 二、元字符:. ^ $ * + ? {} [] | () \

一、元字符之(  . ^ $ * + ? { }  )

import re
ret=re.findall('si..n','qwerwrsimonreorerge') #['simon']
print(ret) ret=re.findall('^s...n','simonreorserpnerge') #['simon'] print(ret) ret=re.findall('s...n','simonreorserpnerge') #['simon', 'serpn'] print(ret) ret=re.findall('s...n$','simonreorserpnergesrren') #['srren'] print(ret) ret=re.findall('^s*','sssasdfgdsjjuresssss') #['sss'],*:表示0到無窮次 +:表示1到無窮次 print(ret) ret=re.findall('alex*','asdfhfalexxx') # print(ret) #['alexxx']  ret=re.findall('alex+','asdfhfalexxx') #[1,+oo] print(ret) #['alexxx']  ret=re.findall('alex*','asdfhfale') #['ale'] print(ret) ret=re.findall('alex+','asdfhfale') #[] print(ret) ret=re.findall('simon?','asdhfsimonnn') #[0,1],?:表示匹配0到1個 print(ret) #['simon']  ret=re.findall('simon{1,3}','asdhfsimonnnnnn') #['simonnn'] 貪婪匹配 print(ret)

注意:前面*,+,?等都是貪婪匹配,也就是儘量多匹配,後面加?號使其變成惰性匹配

ret=re.findall('abc*?','abcccccc')
print(ret)  #['ab']

二、元字符之字符集[   ]:

##---------------------------字符集[]
ret=re.findall('www[simon  baidu]','wwwbaidu')
print(ret) ret=re.findall('x[yz]','xyuuuu') print(ret) ret=re.findall('x[yz]','xyuuxzuu') #['xy', 'xz'] print(ret) ret=re.findall('x[yz]p','xypuuxzpuu') #['xyp', 'xzp'] print(ret) ret=re.findall('x[y,z]p','xypuuxzpux,pu') #['xyp', 'xzp', 'x,p'] print(ret) ret=re.findall('q[a*z]','xypuuxzpqaa') #['qa'] print(ret) ret=re.findall('q[a-z]*','quouuiuni') #['quouuiuni'] print(ret) ret=re.findall('q[a-z]*','quouuiuni9') #['quouuiuni'] print(ret) ret=re.findall('q[0-9]*','q8910uouuiuni9') #['q8910'] print(ret) ret=re.findall('q[0-9]*','q8910uouuiuniq9') #['q8910', 'q9'] print(ret) ret=re.findall('q[^a-z]*','q821') #['q821'] print(ret)

三、元字符之轉義符\

反斜槓後邊跟元字符去除特殊功能,好比\.
反斜槓後邊跟普通字符實現特殊功能,好比\d

\d  匹配任何十進制數;它至關於類 [0-9]。
\D 匹配任何非數字字符;它至關於類 [^0-9]。 \s 匹配任何空白字符;它至關於類 [ \t\n\r\f\v]。 \S 匹配任何非空白字符;它至關於類 [^ \t\n\r\f\v]。 \w 匹配任何字母數字字符;它至關於類 [a-zA-Z0-9_]。 \W 匹配任何非字母數字字符;它至關於類 [^a-zA-Z0-9_] \b 匹配一個特殊字符邊界,好比空格 ,&,#等
import re
print(re.findall("^I","hello I am LIST")) print(re.findall(r"I\b","hello I am LIST")) #['I'] print(re.findall("I\\b","hello I am LIST")) #['I'] print(re.findall(r"c\\l","abc\lerwt")) #['c\\l'] print(re.findall("c\\\\l","abc\lerwt")) #['c\\l']

四、元字符之分組()

m = re.findall(r'(ad)+','add')
print(m) ret=re.search('(?P<id>\d{2})/(?P<name>\w{3})','23/com') print(ret.group()) # 23/com print(ret.group('id')) #23  ret=re.search("(?P<name>[a-z]+)\d+","123simon27zhurui24william45").group() print(ret) #simon27  ret=re.search("(?P<name>[a-z]+)\d+","123simon27zhurui24william45").group('name') print(ret) #simon  ret=re.search("(?P<name>[a-z]+)(?P<age>\d+)","123simon27zhurui24william45").group('age') #.group是固定格式 print(ret) #27

五、元字符之 |

ret=re.search('(ab)|\d','rabhdg8sdgrui') #ab
print(ret.group()) 

六、re模塊下的經常使用方法

import re

#方法1
print(re.findall("s","simon zhu"))   #['s'],返回全部知足匹配條件的結果,放在列表裏

#方法2
ret=re.search("(?P<name>[a-z]+)(?P<age>\d+)","123simon27zhurui24william45").group('age') #函數會在字符串內查找模式匹配,只找到第一個匹配而後返回一個包含匹配信息的對象,該對象能夠經過調用group()方法獲得匹配的字符串,若是字符串沒有匹配,則返回None
print(ret) #27

#方法3
print(re.match("\d+","23simon24zhurui23will78")) #同search,不過盡在字符串開始處進行匹配

#方法4
ret=re.split("[ab]","abcd") #先按'a'分割獲得' ' 和'bcd',在對' '和'bcd'分別按'b'分割
print(ret) #['', '', 'cd']

#方法5
 ret=re.sub('\d','abc','simon7zhurui9',1) print(ret) #simonabczhurui9  ret=re.subn('\d','abc','alvin5yuan6') print(ret)#('alvinabcyuanabc', 2) #方法6 obj=re.compile('\d{3}') ret=obj.search('abc123eeee') print(ret.group())#123  ret=re.finditer('\d','ds3sy4784a') print(ret) #<callable_iterator object at 0x10195f940> print(next(ret).group()) print(next(ret).group())

注意:

ret=re.findall('www.(baidu|oldboy).com','www.oldboy.com')
print(ret)#['oldboy']     這是由於findall會優先把匹配結果組裏內容返回,若是想要匹配結果,取消權限便可
 ret=re.findall('www.(?:baidu|oldboy).com','www.oldboy.com') print(ret)#['www.oldboy.com']  ret=re.findall("www\.(baidu|163)\.com","fddsfsfdwww.baidu.comrerggetbbvfd") print(ret) #['baidu']  ret=re.findall("www\.(?:baidu|163)\.com","fddsfsfdwww.baidu.comrerggetbbvfd") print(ret) #['www.baidu.com']

補充:

import re

print(re.findall("<(?P<tag_name>\w+)>\w+</(?P=tag_name)>","<h1>hello</h1>")) print(re.search("<(?P<tag_name>\w+)>\w+</(?P=tag_name)>","<h1>hello</h1>")) print(re.search(r"<(\w+)>\w+</\1>","<h1>hello</h1>"))

補充2:

#匹配出全部的整數
import re

#ret=re.findall(r"\d+{0}]","1-2*(60+(-40.35/5)-(-4*3))")
ret=re.findall(r"-?\d+\.\d*|(-?\d+)","1-2*(60+(-40.35/5)-(-4*3))") ret.remove("") print(ret)
相關文章
相關標籤/搜索