day5-經常使用模塊學習

模塊介紹

模塊,用一坨代碼實現了某個功能的代碼集合。html

相似於函數式編程和麪向過程變成,函數式編程則完成一個功能,其餘代碼用來調用便可,提供了代碼的重用性和代碼間的耦合。而對於一個複雜的功能,可能須要多個函數才成完成(函數又能夠在不一樣的.py文件中),n個.py文件組成的代碼集合就成爲模塊。node

如: os是系統相關的模塊,file是文件操做相關的模塊python

模塊分爲三種:git

  • 自定義模塊
  • 內置標準模塊(又稱標準庫)
  • 開源模塊

自定義模塊和開源模塊的使用參考 http://www.cnblogs.com/wupeiqi/articles/4963027.html 正則表達式

time & datetime模塊

時間相關操做,時間有三種表示方式:算法

  • 時間戳                1970年1月1日以後的秒,即: time.time()
  • 格式化字符串       2018-11-11 11:11,        即:time.strftime('%Y-%m-%d')
  • 結構化時間          元組包含了:年,日,星期等... time.struct_time  即:time.localtime()
import time

# print(time.clock()) #返回處理器時間,3.3開始已廢棄 , 改爲了time.process_time()測量處理器運算時間,不包括sleep時間,不穩定,mac上測不出來
# print(time.altzone)  #返回與utc時間的時間差,以秒計算\
# print(time.asctime()) #返回時間格式"Fri Aug 19 11:14:16 2016",
# print(time.localtime()) #返回本地時間 的struct time對象格式
# print(time.gmtime(time.time()-800000)) #返回utc時間的struc時間對象格式

# print(time.asctime(time.localtime())) #返回時間格式"Fri Aug 19 11:14:16 2016",
#print(time.ctime()) #返回Fri Aug 19 12:38:29 2016 格式, 同上



# 日期字符串 轉成  時間戳
# string_2_struct = time.strptime("2016/05/22","%Y/%m/%d") #將 日期字符串 轉成 struct時間對象格式
# print(string_2_struct)
# #
# struct_2_stamp = time.mktime(string_2_struct) #將struct時間對象轉成時間戳
# print(struct_2_stamp)



#將時間戳轉爲字符串格式
# print(time.gmtime(time.time()-86640)) #將utc時間戳轉換成struct_time格式
# print(time.strftime("%Y-%m-%d %H:%M:%S",time.gmtime()) ) #將utc struct_time格式轉成指定的字符串格式


#時間加減
import datetime

# print(datetime.datetime.now()) #返回 2016-08-19 12:47:03.941925
#print(datetime.date.fromtimestamp(time.time()) )  # 時間戳直接轉成日期格式 2016-08-19
# print(datetime.datetime.now() )
# print(datetime.datetime.now() + datetime.timedelta(3)) #當前時間+3天
# print(datetime.datetime.now() + datetime.timedelta(-3)) #當前時間-3天
# print(datetime.datetime.now() + datetime.timedelta(hours=3)) #當前時間+3小時
# print(datetime.datetime.now() + datetime.timedelta(minutes=30)) #當前時間+30分


#
# c_time  = datetime.datetime.now()
# print(c_time.replace(minute=3,hour=2)) #時間替換

random模塊

隨機數shell

mport random
print random.random()
print random.randint(1,2)
print random.randrange(1,10)

生成隨機驗證碼編程

import random
checkcode = ''
for i in range(4):
    current = random.randrange(0,4)
    if current != i:
        temp = chr(random.randint(65,90))
    else:
        temp = random.randint(0,9)
    checkcode += str(temp)
print checkcode

OS模塊

提供對操做系統進行調用的接口json

os.getcwd() 獲取當前工做目錄,即當前python腳本工做的目錄路徑
os.chdir("dirname")  改變當前腳本工做目錄;至關於shell下cd
os.curdir  返回當前目錄: ('.')
os.pardir  獲取當前目錄的父目錄字符串名:('..')
os.makedirs('dirname1/dirname2')    可生成多層遞歸目錄
os.removedirs('dirname1')    若目錄爲空,則刪除,並遞歸到上一級目錄,如若也爲空,則刪除,依此類推
os.mkdir('dirname')    生成單級目錄;至關於shell中mkdir dirname
os.rmdir('dirname')    刪除單級空目錄,若目錄不爲空則沒法刪除,報錯;至關於shell中rmdir dirname
os.listdir('dirname')    列出指定目錄下的全部文件和子目錄,包括隱藏文件,並以列表方式打印
os.remove()  刪除一個文件
os.rename("oldname","newname")  重命名文件/目錄
os.stat('path/filename')  獲取文件/目錄信息
os.sep    輸出操做系統特定的路徑分隔符,win下爲"\\",Linux下爲"/"
os.linesep    輸出當前平臺使用的行終止符,win下爲"\r\n",Linux下爲"\n"
os.pathsep    輸出用於分割文件路徑的字符串
os.name    輸出字符串指示當前使用平臺。win->'nt'; Linux->'posix'
os.system("bash command")  運行shell命令,直接顯示
os.environ  獲取系統環境變量
os.path.abspath(path)  返回path規範化的絕對路徑
os.path.split(path)  將path分割成目錄和文件名二元組返回
os.path.dirname(path)  返回path的目錄。其實就是os.path.split(path)的第一個元素
os.path.basename(path)  返回path最後的文件名。如何path以/或\結尾,那麼就會返回空值。即os.path.split(path)的第二個元素
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[, path2[, ...]])  將多個路徑組合後返回,第一個絕對路徑以前的參數將被忽略
os.path.getatime(path)  返回path所指向的文件或者目錄的最後存取時間
os.path.getmtime(path)  返回path所指向的文件或者目錄的最後修改時間

更多猛擊這裏windows

sys模塊

用於提供對解釋器相關的操做

sys.argv           命令行參數List,第一個元素是程序自己路徑
sys.exit(n)        退出程序,正常退出時exit(0)
sys.version        獲取Python解釋程序的版本信息
sys.maxint         最大的Int值
sys.path           返回模塊的搜索路徑,初始化時使用PYTHONPATH環境變量的值
sys.platform       返回操做系統平臺名稱
sys.stdout.write('please:')
val = sys.stdin.readline()[:-1]

更多猛擊這裏

shutil模塊

高級的文件,文件夾,壓縮包 處理模塊

1. shutil.copyfileobj(fsrc,fdst)

把一個文件的內容拷貝到另外一個文件中,能夠部份內容

with open("f_old",'r',encoding="utf-8") as f1,\
    open("f_new","w",encoding="utf-8") as f2:
    shutil.copyfileobj(f1,f2)    #拷貝文件的內容

 2. shutil.copyfile(src,dst)

拷貝文件,可是不拷貝全部權限

shutil.copyfile("f_old","f_new")  #同一目錄下拷貝文件
shutil.copyfile(r'D:\PycharmProjects\pyhomework\day5\shutil_mode\shutil_mod\f_old',r'd:\f_new')    #經過絕對路徑拷貝文件

 3. shutil.copymode(src,dst)

僅拷貝權限。內容、組、用戶均不變

[root@whtest137 ~]# ll
total 8
-rwxr-xr-x 1 root   root   0 Apr  1 16:05 zhangqigao   #有執行權限
-rw-r--r-- 1 whtest whtest 0 Apr  1 16:06 zhangqigao_old  #沒有執行權限
>>> import os,shutil
>>> os.chdir("/root")
#拷貝"zhangqigao_old"權限給"zhangqigao"
>>> shutil.copymode("zhangqigao_old","zhangqigao") 
[root@whtest137 ~]# ll
total 8
-rw-r--r-- 1 root   root   0 Apr  1 16:05 zhangqigao  # 得到跟"zhangqigao_old"同樣的文件權限
-rw-r--r-- 1 whtest whtest 0 Apr  1 16:06 zhangqigao_old
View Code

4.shutil.copystat(src,dst)

拷貝文件的狀態信息,如:mode bits, atime, mtime, flags

#兩個文件的建立時間和用戶權限都不一樣
[root@jenkins_sh temp]# ll
total 0
-rw-r--r-- 1 root    root    0 Apr  1 17:31 zhangqigao
-rwxr-xr-x 1 jenkins jenkins 0 Apr  1 16:26 zhangqigao_old
#python操做
>>> import os,shutil
>>> os.chdir("/temp")
#zhangqigao 這個文件狀態
>>> os.stat("zhangqigao")
posix.stat_result(st_mode=33188, st_ino=76808194, st_dev=2053L, st_nlink=1,
st_uid=0, st_gid=0, st_size=0, st_atime=1491039109, st_mtime=1491039109,
st_ctime=1491039109)
#zhangqigao_old的文件狀態
>>> os.stat("zhangqigao_old")
posix.stat_result(st_mode=33261, st_ino=76808195, st_dev=2053L, st_nlink=1,
st_uid=101, st_gid=103, st_size=0, st_atime=1491035188, st_mtime=1491035188,
st_ctime=1491035242)
#拷貝zhangqigao_old 文件狀態給zhangqigao 文件
>>> shutil.copystat("zhangqigao_old","zhangqigao")
# 拷貝後,zhangqigao文件的文件狀態
>>> os.stat("zhangqigao")
posix.stat_result(st_mode=33261, st_ino=76808194, st_dev=2053L, st_nlink=1,
st_uid=0, st_gid=0, st_size=0, st_atime=1491035188, st_mtime=1491035188,
st_ctime=1491039237)
 
#操做後兩個文件比較
[root@jenkins_sh temp]# ll
total 0
-rwxr-xr-x 1 root    root    0 Apr  1 16:26 zhangqigao  #狀態包括文件權限,文件建立的時間等,不包括文件所屬用戶和用戶組
-rwxr-xr-x 1 jenkins jenkins 0 Apr  1 16:26 zhangqigao_old
View Code

 5. shutil.copy(src,dst)

拷貝文件和權限

#拷貝前
[root@jenkins_sh temp]# ll
total 0
-rwxr-xr-x 1 jenkins jenkins 0 Apr  1 16:26 zhangqigao_old
#拷貝中
>>> import os,shutil
>>> os.chdir("/temp")
>>> shutil.copy("zhangqigao_old","zhangqigao")
#拷貝結果輸出
[root@jenkins_sh temp]# ll
total 0
-rwxr-xr-x 1 root    root    0 Apr  1 17:42 zhangqigao  #拷貝了zhangqigao_old文件和文件權限
-rwxr-xr-x 1 jenkins jenkins 0 Apr  1 16:26 zhangqigao_old
View Code

6. shutil.copy2(src,dst)

拷貝文件和狀態信息

#拷貝前
[root@jenkins_sh temp]# ll
total 0
-rwxr-xr-x 1 jenkins jenkins 0 Apr  1 16:26 zhangqigao_old
#拷貝中
>>> import os,shutil
>>> os.chdir("/temp")
>>> shutil.copy2("zhangqigao_old","zhangqigao")
#拷貝後
[root@jenkins_sh temp]# ll
total 0
-rwxr-xr-x 1 root    root    0 Apr  1 16:26 zhangqigao  #拷貝了zhangqigao_old的文件和狀態
-rwxr-xr-x 1 jenkins jenkins 0 Apr  1 16:26 zhangqigao_old
View Code

7. shutil.copytree(src,dst)

遞歸去拷貝文件,至關於cp -r

#操做前
[root@jenkins_sh temp]# ll
total 4
drwxr-xr-x 2 root root 4096 Apr  1 17:53 xiaogao
[root@jenkins_sh temp]# cd xiaogao/;ll
total 0
-rwxr-xr-x 1 root    root    0 Apr  1 16:26 zhangqigao
-rwxr-xr-x 1 jenkins jenkins 0 Apr  1 16:26 zhangqigao_old
#操做中
>>> import os,shutil
>>> os.chdir("/temp")
>>> shutil.copytree("xiaogao","gaogao")  #遞歸拷貝
#操做結果
[root@jenkins_sh temp]# ll
total 8
drwxr-xr-x 2 root root 4096 Apr  1 17:53 gaogao   #拷貝成功
drwxr-xr-x 2 root root 4096 Apr  1 17:53 xiaogao
[root@jenkins_sh temp]# cd gaogao/;ll
total 0
-rwxr-xr-x 1 root root 0 Apr  1 16:26 zhangqigao
-rwxr-xr-x 1 root root 0 Apr  1 16:26 zhangqigao_old
View Code

 

8. shutil.rmtree(path[,ignore_errors[,onerror]])

遞歸去刪除文件,至關於rm -rf

#操做前
[root@jenkins_sh temp]# ll
total 4
drwxr-xr-x 2 root root 4096 Apr  1 17:53 xiaogao
[root@jenkins_sh temp]# cd xiaogao/;ll
total 0
-rwxr-xr-x 1 root    root    0 Apr  1 16:26 zhangqigao
-rwxr-xr-x 1 jenkins jenkins 0 Apr  1 16:26 zhangqigao_old
#操做中
>>> import os,shutil
>>> os.chdir("/temp")
>>> shutil.rmtree("xiaogao")
#操做結果
[root@jenkins_sh temp]# ll
total 0    #成功刪除xiaogao目錄
View Code

9. shutil.move(src,dst)

遞歸的去移動文件,至關於mv

#操做前
[root@jenkins_sh temp]# ll
total 4
drwxr-xr-x 2 root root 4096 Apr  1 18:07 xiaogao
-rw-r--r-- 1 root root    0 Apr  1 18:07 zhangqigao
#操做中
>>> import shutil
>>> shutil.move("/temp/zhangqigao","/temp/xiaogao")   #把文件移到目錄中
#操做結果
[root@jenkins_sh xiaogao]# ll
total 4
drwxr-xr-x 2 root root 4096 Apr  1 18:08 xiaogao
[root@jenkins_sh temp]# cd xiaogao/;ll
total 0
-rw-r--r-- 1 root root 0 Apr  1 18:07 zhangqigao
View Code

10.shutil.make_archive((base_name, format, root_dir=None,base_dir=None,verbose=0,dry=0,owner=None,group=None,logger=None)

建立壓縮包並返回文件路徑,例如:zip、tar

  • base_name: 壓縮包的文件名,也能夠是壓縮包的路徑。只是文件名時,則保存至當前目錄,不然保存至指定路徑,
    • 如:www                        =>保存至當前路徑
    • 如:/Users/wupeiqi/www =>保存至/Users/wupeiqi/
  • format: 壓縮包種類,「zip」, 「tar」, 「bztar」,「gztar」
  • root_dir: 要壓縮的文件夾路徑(默認當前目錄)
  • owner: 用戶,默認當前用戶
  • group: 組,默認當前組
  • logger: 用於記錄日誌,一般是logging.Logger對象
#將 /Users/wupeiqi/Downloads/test 下的文件打包放置當前程序目錄
 
import shutil
ret = shutil.make_archive("wwwwwwwwww", 'gztar', root_dir='/Users/wupeiqi/Downloads/test')
 
 
#將 /Users/wupeiqi/Downloads/test 下的文件打包放置 /Users/wupeiqi/目錄
import shutil
ret = shutil.make_archive("/Users/wupeiqi/wwwwwwwwww", 'gztar', root_dir='/Users/wupeiqi/Downloads/test')
View Code

11. zipfile

以zip的形式壓縮文件,注意了這個只能壓縮文件,不能壓縮目錄,若是壓縮,也只能顯示空目錄。

import zipfile
 
# 壓縮
z = zipfile.ZipFile('laxi.zip', 'w')
z.write('a.log')  #寫入
z.write('data.data')
z.close()   #關閉
 
# 解壓
z = zipfile.ZipFile('laxi.zip', 'r')
z.extractall()   #解壓
z.close()
View Code

12. tarfile

以tar的形式打包文件,這邊能打包全部文件,包括目錄

import tarfile
 
# 打包
tar = tarfile.open('your.tar','w')
 
#不加arcname打的是絕對路徑,也就是/Users/wupeiqi/PycharmProjects/bbs2.zip,加這個表示你在your.tar中加什麼文件就寫什麼文件名,也就是bbs2.zip
tar.add('/Users/wupeiqi/PycharmProjects/bbs2.zip', arcname='bbs2.zip')
tar.add('/Users/wupeiqi/PycharmProjects/cmdb.zip', arcname='cmdb.zip')
tar.close()
 
# 解壓
tar = tarfile.open('your.tar','r')
tar.extractall()  # 可設置解壓地址
tar.close()
View Code

 參考:http://www.cnblogs.com/wupeiqi/articles/4963027.html

json & pickle模塊

用於序列化的兩個模塊 

  • json, 用於字符串和python數據類型間進行轉換
  • pickle, 用於python特有的類型和python數據類型間進行轉換

Json模塊提供了四個功能:dumps, dump, loads, load

pickle模塊提供了四個功能:dumps, dump, loads, load

使用方法參考:這裏

shelve模塊

shelve模塊是一個簡單的k,v將內存數據經過文件持久化的模塊,能夠持久化任何pickle可支持的python數據格式

import shelve
 
d = shelve.open('shelve_test') #打開一個文件
 
class Test(object):
    def __init__(self,n):
        self.n = n
 
 
t = Test(123) 
t2 = Test(123334)
 
name = ["alex","rain","test"]
d["test"] = name #持久化列表
d["t1"] = t      #持久化類
d["t2"] = t2
 
d.close()

詳細使用方法實例:http://www.cnblogs.com/zhangqigao/articles/6672235.html

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>
View Code

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)

修改和刪除xml文檔內容

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) #打印生成的格式

ConfigParser模塊

用於生成和修改常見配置文檔,當前模塊的名稱在python3.x版本中變動爲configparser

文檔格式以下

[DEFAULT]
ServerAliveInterval = 45
Compression = yes
CompressionLevel = 9
ForwardX11 = yes
 
[bitbucket.org]
User = hg
 
[topsecret.server.com]
Port = 50022
ForwardX11 = no

若是想用python生成一個這樣的文檔怎麼作呢?

import configparser
 
config = configparser.ConfigParser()
config["DEFAULT"] = {'ServerAliveInterval': '45',
                      'Compression': 'yes',
                     'CompressionLevel': '9'}
 
config['bitbucket.org'] = {}
config['bitbucket.org']['User'] = 'hg'
config['topsecret.server.com'] = {}
topsecret = config['topsecret.server.com']
topsecret['Host Port'] = '50022'     # mutates the parser
topsecret['ForwardX11'] = 'no'  # same here
config['DEFAULT']['ForwardX11'] = 'yes'
with open('example.ini', 'w') as configfile:
   config.write(configfile)

寫完了還能夠再讀出來

>>> import configparser
>>> config = configparser.ConfigParser()
>>> config.sections()
[]
>>> config.read('example.ini')
['example.ini']
>>> config.sections()
['bitbucket.org', 'topsecret.server.com']
>>> 'bitbucket.org' in config
True
>>> 'bytebong.com' in config
False
>>> config['bitbucket.org']['User']
'hg'
>>> config['DEFAULT']['Compression']
'yes'
>>> topsecret = config['topsecret.server.com']
>>> topsecret['ForwardX11']
'no'
>>> topsecret['Port']
'50022'
>>> for key in config['bitbucket.org']: print(key)
...
user
compressionlevel
serveraliveinterval
compression
forwardx11
>>> config['bitbucket.org']['ForwardX11']
'yes'

 configparser增刪改查語法

[section1]
k1 = v1
k2:v2
  
[section2]
k1 = v1
 
import ConfigParser
  
config = ConfigParser.ConfigParser()
config.read('i.cfg')
  
# ########## 讀 ##########
#secs = config.sections()
#print secs
#options = config.options('group2')
#print options
  
#item_list = config.items('group2')
#print item_list
  
#val = config.get('group1','key')
#val = config.getint('group1','key')
  
# ########## 改寫 ##########
#sec = config.remove_section('group1')
#config.write(open('i.cfg', "w"))
  
#sec = config.has_section('wupeiqi')
#sec = config.add_section('wupeiqi')
#config.write(open('i.cfg', "w"))
  
  
#config.set('group2','k1',11111)
#config.write(open('i.cfg', "w"))
  
#config.remove_option('group2','age')
#config.write(open('i.cfg', "w"))

hashlib模塊

用於加密相關的操做,3.x裏代替了md5模塊和sha模塊,主要提供SHA1, SHA224, SHA256, SHA384, SHA512, MD5算法

import hashlib
 
m = hashlib.md5()
m.update(b"Hello")
m.update(b"It's me")
print(m.digest())
m.update(b"It's been a long time since last time we ...")
 
print(m.digest()) #2進制格式hash
print(len(m.hexdigest())) #16進制格式hash
'''
def digest(self, *args, **kwargs): # real signature unknown
    """ Return the digest value as a string of binary data. """
    pass
 
def hexdigest(self, *args, **kwargs): # real signature unknown
    """ Return the digest value as a string of hexadecimal digits. """
    pass
 
'''
import hashlib
 
# ######## md5 ########
 
hash = hashlib.md5()
hash.update('admin')
print(hash.hexdigest())
 
# ######## sha1 ########
 
hash = hashlib.sha1()
hash.update('admin')
print(hash.hexdigest())
 
# ######## sha256 ########
 
hash = hashlib.sha256()
hash.update('admin')
print(hash.hexdigest())
 
 
# ######## sha384 ########
 
hash = hashlib.sha384()
hash.update('admin')
print(hash.hexdigest())
 
# ######## sha512 ########
 
hash = hashlib.sha512()
hash.update('admin')
print(hash.hexdigest())

 python 還有一個 hmac 模塊,它內部對咱們建立 key 和 內容 再進行處理而後再加密

散列消息鑑別碼,簡稱HMAC,是一種基於消息鑑別碼MAC(Message Authentication Code)的鑑別機制。使用HMAC時,消息通信的雙方,經過驗證消息中加入的鑑別密鑰K來鑑別消息的真僞;

通常用於網絡通訊中消息加密,前提是雙方先要約定好key,就像接頭暗號同樣,而後消息發送把用key把消息加密,接收方用key + 消息明文再加密,拿加密後的值 跟 發送者的相對比是否相等,這樣就能驗證消息的真實性,及發送者的合法性了。

import hmac
h = hmac.new(b'天王蓋地虎', b'寶塔鎮河妖')
print h.hexdigest()

 更多關於md5,sha1,sha256等介紹的文章看這裏https://www.tbs-certificates.co.uk/FAQ/en/sha256.html

subprocess 模塊

在沒有subprocess這個模塊的時候,經過os.system(),os.popen(),commands這三個模塊和操做系統作交互

1. os.system()

做用:執行操做系統命令,只返回命令的執行狀態(0:成功,非0:失敗),不返回命令的執行結果

>>> import os
>>> os.system("ls -l")
total 16708
-rw-------. 1 root root     1350 Jan  4 01:51 anaconda-ks.cfg
-rw-r--r--. 1 root root     8017 Jan  4 01:51 install.log
0  #執行返回的狀態
>>> res = os.system("ls -l")
total 16708
-rw-------. 1 root root     1350 Jan  4 01:51 anaconda-ks.cfg
-rw-r--r--. 1 root root     8017 Jan  4 01:51 install.log
>>> res
0   #0: 表示成功
>>> res = os.system("lm")
sh: lm: command not found
>>> res
32512  #非0:表示失敗

2. os.popen()

做用:執行操做系統命令,不返回命令的執行狀態,只返回命令的執行結果。

>>> import os
>>> os.popen("ls -l")
<open file 'ls -l', mode 'r' at 0x7f5ded070540>
>>> res = os.popen("ls -l")
>>> a = res.read()
>>> print(a)  #打印返回結果
total 16708
-rw-------. 1 root root     1350 Jan  4 01:51 anaconda-ks.cfg
-rw-r--r--. 1 root root     8017 Jan  4 01:51 install.log

注:執行popen() 不是直接返回命令的執行結果的,而是須要read一下,這是由於popen至關於打開了一個文件,它把結果存到文件中,只不過它是至關於存在內存中了,可是你好像打開文件的樣子去取同樣。

3. commands模塊

做用:便可以獲取命令的執行狀態,也能夠獲取命令的執行結果,可是隻能在python2.7有這個命令,在python3.5以後就沒有,還有就是這個模塊只支持Linux, Windows不支持,這裏知道這個命令就好了。

>>> import commands  #導入commands命令
>>> commands.getstatusoutput("ls -l")
(0, 'total 16708\n-rw-------. 1 root root     1350 Jan  4 01:51 anaconda-ks.cfg\n
-rw-r--r--. 1 root root     8017 Jan  4 01:51 install.log') #元組的形式返回
>>> res = commands.getstatusoutput("ls -l")
>>> res[0]  #執行狀態
0
>>> print(res[1])  #執行結果
total 16708
-rw-------. 1 root root     1350 Jan  4 01:51 anaconda-ks.cfg
-rw-r--r--. 1 root root     8017 Jan  4 01:51 install.log

 

上面說的commands模塊在python3.5之後的版本就沒有了,並且它又不支持windows,因此python3.5以後又出來新的模塊更爲強大,subprocess模塊

1. subprocess.run()

做用: 運行命令,返回命令的執行結果(Python3.5之後的版本纔會有這個命令)

>>> import subprocess
# python 解析則傳入命令的每一個參數的列表
>>> subprocess.run(["df","-h"])
Filesystem            Size  Used Avail Use% Mounted on
/dev/mapper/VolGroup-LogVol00
                      289G   70G  204G  26% /
tmpfs                  64G     0   64G   0% /dev/shm
/dev/sda1             283M   27M  241M  11% /boot
CompletedProcess(args=['df', '-h'], returncode=0)
# 須要交給Linux shell本身解析,則:傳入命令字符串,shell=True
>>> subprocess.run("df -h|grep /dev/sda1",shell=True)
/dev/sda1             283M   27M  241M  11% /boot
CompletedProcess(args='df -h|grep /dev/sda1', returncode=0)

注:執行的命令須要讓python去解釋執行這個命令,執行的命令以及參數,須要以列表的形式傳入。第二種狀況:可是若是須要交給Linux shell環境去解析的還,這傳入命令的字符串,而且聲明shell=True便可

2. subprocess.call()

做用:執行命令,返回命令的狀態,0或者非0 

>>> import subprocess
>>> res = subprocess.call(["ls","-l"])
total 26976
-rw-r--r--  1 1000 1000    10914 Jan 17 15:57 aclocal.m4
drwxr-xr-x  5 root root     4096 May 12 14:21 build
-rwxr-xr-x  1 1000 1000    43940 Jan 17 15:57 config.guess
>>> res  #返回命令的狀態
0

3. subprocess.check_call()

做用:執行命令,若是執行結果爲0,正常返回,不然拋出異常

>>> import subprocess
>>> res = subprocess.check_call(["ls","-l"])
total 26976
-rw-r--r--  1 1000 1000    10914 Jan 17 15:57 aclocal.m4
drwxr-xr-x  5 root root     4096 May 12 14:21 build
>>> res
0

4. subprocess.getstatusoutput()

做用: 接受字符串形式的命令,返回元組形式,第一個元素是執行狀態,第二個是命令結果

>>> import subprocess
>>> subprocess.getstatusoutput('ls /bin/ls')
(0, '/bin/ls') #0:執行狀態,'bin/ls':執行結果

5. subprocess.getoutput()

做用: 接受字符串形式的命令,而且返回命令的結果

>>> import subprocess
>>> subprocess.getoutput('ls /bin/ls')
'/bin/ls'   #返回命令的結果

6. subprocess.check_output()

做用: 執行命令,而且返回結果,不是打印

>>> import subprocess
>>> res = subprocess.check_output(["ls","-l"])
>>> res
b'total 26976\n-rw-r--r--  1 1000 1000    10914 Jan 17 15:57 aclocal.m4\n
drwxr-xr-x  5 root root     4096 May 12 14:21 build\n
-rwxr-xr-x  1 1000 1000    43940 Jan 17 15:57 config.guess\n
-rw-r--r--  1 root root   756903 May 12 14:18 config.log\n'   #這邊是以字節類型返回的

logging模塊

不少程序都有記錄日誌的需求,而且日誌中包含的信息即有正常的程序訪問日誌,還可能有錯誤,警告等信息輸出,python的logging模塊提供了標準的日誌接口,你能夠經過它存儲各類格式的日誌,logging的日誌能夠分爲debug,info,warning,error和critical 5個級別,下面咱們看看這個日誌模塊logging怎麼用

一. 簡單用法

說明:日誌級別有五個,分別是,debug, info ,warning, error 和critical ,其中debug級別最低,critical級別最高,級別越低,打印的日誌越多

import logging
 
logging.debug("logging debug")
logging.info("logging info")
logging.warning("user [abc] attempted wrong password more than 3 times")
logging.error("logging error")
logging.critical("logging critical")
 
#輸出
WARNING:root:user [abc] attempted wrong password more than 3 times
ERROR:root:logging error
CRITICAL:root:logging critical

1.1. 日誌級別

看一下這幾個日誌級別分別表明什麼意思

Level When it’s used
DEBUG Detailed information, typically of interest only when diagnosing problems.
INFO Confirmation that things are working as expected.
WARNING An indication that something unexpected happened, or indicative of some problem in the near future (e.g. ‘disk space low’). The software is still working as expected.
ERROR Due to a more serious problem, the software has not been able to perform some function.
CRITICAL A serious error, indicating that the program itself may be unable to continue running.

1.2. 日誌寫入文件

import logging
 
logging.basicConfig(filename="catalina.log",level=logging.INFO) #輸入文件名,和日誌級別
#---日誌輸出---
logging.debug("logging debug")
logging.info("logging info")
logging.warning("logging warning")
 
#輸出到文件中的內容
INFO:root:logging info
WARNING:root:logging warning

注: 這句中的level=loggin.INFO意思是,把日誌紀錄級別設置爲INFO,也就是說,只有比日誌是INFO或比INFO級別更高的日誌纔會被紀錄到文件裏,因此debug日誌沒有記錄,若是想記錄,則級別設置成debug也就是level=loggin.DEBUG

1.3. 加入日期格式

logging.basicConfig(filename="catalina.log",
                    level=logging.INFO,
                    format='%(asctime)s %(module)s:%(levelname)s %(message)s', #格式請見第5點內容
                    datefmt='%m/%d/%Y %H:%M:%S %p') #須要加上format和datefmt
 
#----日誌內容-----
logging.debug("logging debug")
logging.info("logging info")
logging.warning("logging warning")
 
#文件輸出
04/11/2017 14:20:22 PM logging_mod:INFO logging info
04/11/2017 14:20:22 PM logging_mod:WARNING logging warning

1.4. format的日誌格式

%(name)s

Logger的名字

%(levelno)s

數字形式的日誌級別

%(levelname)s

文本形式的日誌級別

%(pathname)s

調用日誌輸出函數的模塊的完整路徑名,可能沒有

%(filename)s

調用日誌輸出函數的模塊的文件名

%(module)s

調用日誌輸出函數的模塊名

%(funcName)s

調用日誌輸出函數的函數名

%(lineno)d

調用日誌輸出函數的語句所在的代碼行

%(created)f

當前時間,用UNIX標準的表示時間的浮 點數表示

%(relativeCreated)d

輸出日誌信息時的,自Logger建立以 來的毫秒數

%(asctime)s

字符串形式的當前時間。默認格式是 「2003-07-08 16:49:45,896」。逗號後面的是毫秒

%(thread)d

線程ID。可能沒有

%(threadName)s

線程名。可能沒有

%(process)d

進程ID。可能沒有

%(message)s

用戶輸出的

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

二. 複雜日誌輸出

以前的寫法感受要麼就輸入在屏幕上,要麼就是輸入在日誌裏面,那咱們有沒有既能夠輸出在日誌上,又輸出在日誌裏面呢?很明顯,固然能夠。下面咱們就來討論一下,如何使用複雜的日誌輸出。

1 簡介

python使用logging模塊記錄日誌涉及的四個主要類:

①logger:提供了應用程序能夠直接使用的接口。

②handler:將(logger建立的)日誌記錄發送到合適的目的輸出。

③filter:提供了細度設備來決定輸出哪條日誌記錄。

④formatter:決定日誌記錄的最終輸出格式。

2 logger

①每一個程序在輸出信息以前都須要得到一個logger。logger一般對應了程序的模塊名,好比聊天工具的圖形界面模塊能夠這樣得到它的logger:

logger = logging.getLogger("chat.gui")

核心模塊能夠這樣寫:

logger = logging.getLogger("chat.kernel")

②logger.setLevel(lel)

說明:指定最低的日誌級別,低於lel的級別將被忽略(debug是最低的內置級別,critical爲最高)

logger.setLevel(logging.DEBUG)  #設置級別爲debug級別

③Logger.addFilter(filt)、Logger.removeFilter(filt)

說明:添加或刪除指定的filter

④logger.addHandler(hdlr)、logger.removeHandler(hdlr)

說明:增長或刪除指定的handler

logger.addHandler(ch)#添加handler
 
logger.removeHandler(ch) #刪除handler

⑤Logger.debug()、Logger.info()、Logger.warning()、Logger.error()、Logger.critical()

說明:能夠設置的日誌級別

logger.debug('debug message')
logger.info('info message')
logger.warn('warn message')
logger.error('error message')
logger.critical('critical message')

⑤獲取handler個數

handler_len = len(logger.handlers)
print(handler_len)
 
#輸出
1

三、hander

handler對象負責發送相關的信息到指定目的地。Python的日誌系統有多種Handler可使用。有些Handler能夠把信息輸出到控制檯,有些Logger能夠把信息輸出到文件,還有些 Handler能夠把信息發送到網絡上。若是以爲不夠用,還能夠編寫本身的Handler。能夠經過addHandler()方法添加多個多handler 。

①Handler.setLevel(lel)

說明:指定被處理的信息級別,低於lel級別的信息將被忽略。

ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)

②Handler.setFormatter()

說明:給這個handler選擇一個格式

ch_formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s") #生成格式
 
ch.setFormatter(ch_formatter) #設置格式

③Handler.addFilter(filt)、Handler.removeFilter(filt)

說明:新增或刪除一個filter對象

三. handler詳解

一、logging.StreamHandler

說明:使用這個Handler能夠向相似與sys.stdout或者sys.stderr的任何文件對象(file object)輸出信息,也就是屏幕輸出。

它的構造函數是:StreamHandler([strm]),其中strm參數是一個文件對象,默認是sys.stderr。

import logging
 
logger = logging.getLogger("TEST-LOG")
logger.setLevel(logging.DEBUG)
 
ch = logging.StreamHandler() #建立一個StreamHandler對象
ch.setLevel(logging.DEBUG) #設置輸出StreamHandler日誌級別
 
ch_formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
ch.setFormatter(ch_formatter)  #設置時間格式
logger.addHandler(ch)
 
# 'application' code
logger.debug('debug message')
logger.info('info message')
logger.warn('warn message')
logger.error('error message')
logger.critical('critical message')
 
#輸出
2017-04-11 16:42:49,764 - TEST-LOG - DEBUG - debug message
2017-04-11 16:42:49,764 - TEST-LOG - INFO - info message
2017-04-11 16:42:49,764 - TEST-LOG - WARNING - warn message
2017-04-11 16:42:49,765 - TEST-LOG - ERROR - error message
2017-04-11 16:42:49,765 - TEST-LOG - CRITICAL - critical message

二、logging.FileHandler

說明:和StreamHandler相似,用於向一個文件輸出日誌信息,不過FileHandler會幫你打開這個文件。

它的構造函數是:FileHandler(filename[,mode])。filename是文件名,必須指定一個文件名。mode是文件的打開方式。參見Python內置函數open()的用法。默認是’a',即添加到文件末尾。

import logging
 
#create logging
logger = logging.getLogger("TEST-LOG")
logger.setLevel(logging.DEBUG)
 
fh = logging.FileHandler("debug.log",encoding="utf-8") #日誌輸出到debug.log文件中
fh.setLevel(logging.INFO) #設置FileHandler日誌級別
 
fh_formatter = logging.Formatter("%(asctime)s %(module)s:%(levelname)s %(message)s")
 
fh.setFormatter(fh_formatter)
 
logger.addHandler(fh)
 
# 'application' code
logger.info('info message')
logger.warn('warn message')
logger.error('error message')
logger.critical('critical message')
 
#輸出到文件中
2017-04-11 17:09:50,035 logging_screen_output:INFO info message
2017-04-11 17:09:50,035 logging_screen_output:WARNING warn message
2017-04-11 17:09:50,035 logging_screen_output:ERROR error message
2017-04-11 17:09:50,035 logging_screen_output:CRITICAL critical message

三、logging.handlers.RotatingFileHandler

說明:這個Handler相似於上面的FileHandler,可是它能夠管理文件大小。當文件達到必定大小以後,它會自動將當前日誌文件更名,而後建立 一個新的同名日誌文件繼續輸出。好比日誌文件是chat.log。當chat.log達到指定的大小以後,RotatingFileHandler自動把 文件更名爲chat.log.1。不過,若是chat.log.1已經存在,會先把chat.log.1重命名爲chat.log.2。。。最後從新建立 chat.log,繼續輸出日誌信息。

它的構造函數是:RotatingFileHandler( filename[, mode[, maxBytes[, backupCount]]]),其中filename和mode兩個參數和FileHandler同樣。

maxBytes用於指定日誌文件的最大文件大小。若是maxBytes爲0,意味着日誌文件能夠無限大,這時上面描述的重命名過程就不會發生。

backupCount用於指定保留的備份文件的個數。好比,若是指定爲2,當上面描述的重命名過程發生時,原有的chat.log.2並不會被改名,而是被刪除。

import logging
from logging import handlers  #須要導入handlers
 
logger = logging.getLogger(__name__)
log_file = "timelog.log"
 
#按文件大小來分割,10個字節,保留個數是3個
fh = handlers.RotatingFileHandler(filename=log_file,maxBytes=10,backupCount=3)
formatter = logging.Formatter('%(asctime)s %(module)s:%(lineno)d %(message)s')
fh.setFormatter(formatter)
logger.addHandler(fh)
 
logger.warning("test1")
logger.warning("test12")
logger.warning("test13")
logger.warning("test14")

四、logging.handlers.TimedRotatingFileHandler

說明:這個Handler和RotatingFileHandler相似,不過,它沒有經過判斷文件大小來決定什麼時候從新建立日誌文件,而是間隔必定時間就 自動建立新的日誌文件。重命名的過程與RotatingFileHandler相似,不過新的文件不是附加數字,而是當前時間。

它的構造函數是:TimedRotatingFileHandler( filename [,when [,interval [,backupCount]]]),其中filename參數和backupCount參數和RotatingFileHandler具備相同的意義。

interval是時間間隔。when參數是一個字符串。表示時間間隔的單位,不區分大小寫。它有如下取值:①S:秒②M:分③H:小時④D:天⑤W :每星期(interval==0時表明星期一)⑥midnight:天天凌晨

import logging
from logging import handlers
import time
 
logger = logging.getLogger(__name__)
log_file = "timelog.log"
#按時間來分割文件,按5秒一次分割,保留日誌個數是3個
fh = handlers.TimedRotatingFileHandler(filename=log_file,when="S",interval=5,backupCount=3)
formatter = logging.Formatter('%(asctime)s %(module)s:%(lineno)d %(message)s')
fh.setFormatter(formatter)
logger.addHandler(fh)
 
logger.warning("test1")
time.sleep(2)
logger.warning("test12")
time.sleep(2)
logger.warning("test13")
time.sleep(2)
logger.warning("test14")
logger.warning("test15")

四. 控制檯和文件日誌共同輸出

須要什麼樣的輸出,只須要添加相應的handler就ok了

一、邏輯圖

2. 代碼以下:

import logging
 
#create logging
logger = logging.getLogger("TEST-LOG")
logger.setLevel(logging.DEBUG)
 
#屏幕handler
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
 
#文件handler
fh = logging.FileHandler("debug.log",encoding="utf-8")
fh.setLevel(logging.INFO)
#分別建立輸出日誌格式
ch_formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
fh_formatter = logging.Formatter("%(asctime)s %(module)s:%(levelname)s %(message)s")
#設置handler的輸出格式
ch.setFormatter(ch_formatter)
fh.setFormatter(fh_formatter)
#添加handler
logger.addHandler(ch)
logger.addHandler(fh)
 
# 'application' code
logger.debug('debug message')
logger.info('info message')
logger.warn('warn message')
logger.error('error message')
logger.critical('critical message')

注:若是添加時間分割或者文件大小分割,再添加handler便可。添加方式請見第三節中的三、4點

re模塊

經常使用正則表達式符號

'.'     默認匹配除\n以外的任意一個字符,若指定flag DOTALL,則匹配任意字符,包括換行
'^'     匹配字符開頭,若指定flags MULTILINE,這種也能夠匹配上(r"^a","\nabc\neee",flags=re.MULTILINE)
'$'     匹配字符結尾,或e.search("foo$","bfoo\nsdfsf",flags=re.MULTILINE).group()也能夠
'*'     匹配*號前的字符0次或屢次,re.findall("ab*","cabb3abcbbac")  結果爲['abb', 'ab', 'a']
'+'     匹配前一個字符1次或屢次,re.findall("ab+","ab+cd+abb+bba") 結果['ab', 'abb']
'?'     匹配前一個字符1次或0次
'{m}'   匹配前一個字符m次
'{n,m}' 匹配前一個字符n到m次,re.findall("ab{1,3}","abb abc abbcbbb") 結果'abb', 'ab', 'abb']
'|'     匹配|左或|右的字符,re.search("abc|ABC","ABCBabcCD").group() 結果'ABC'
'(...)' 分組匹配,re.search("(abc){2}a(123|456)c", "abcabca456c").group() 結果 abcabca456c
'\'     轉義
 
[a-z]   匹配[a-z]
[A-Z]   匹配[A-Z]
[0-9]   匹配數字0-9
'\A'    只從字符開頭匹配,re.search("\Aabc","alexabc") 是匹配不到的
'\Z'    匹配字符結尾,同$
'\d'    匹配數字0-9
'\D'    匹配非數字
'\w'    匹配[A-Za-z0-9]
'\W'    匹配非[A-Za-z0-9]
's'     匹配空白字符、\t、\n、\r , re.search("\s+","ab\tc1\n3").group() 結果 '\t'
'(?P<name>...)' 分組匹配 re.search("(?P<province>[0-9]{4})(?P<city>[0-9]{2})(?P<birthday>[0-9]{4})","371481199306143242").groupdict("city")
結果:{'province': '3714', 'city': '81', 'birthday': '1993'}

1、 經常使用匹配方法

re.match 從頭開始匹配
re.search 匹配包含
re.findall 把全部匹配到的字符放到以列表中的元素返回
re.split    以匹配到的字符當作列表分隔符
re.sub      匹配字符並替換

一、re.match(pattern, string, flags=0)

說明:在string的開始處匹配模式

>>> import re
>>> a = re.match('in',"inet addr:10.161.146.134")  #從頭開始匹配in字符
>>> a.group()
'in'
 
>>> a = re.match('addr',"inet addr:10.161.146.134")   #開頭匹配不到,因此返回none
>>> print(a)
None

 二、re.search(pattern, string, flags=0)

說明:在string中尋找模式

>>> import re
>>> a = re.search('addr',"inet addr:10.161.146.134")  #在字符串中尋找
>>> a.group()
'addr'

三、re.findall(pattern, string, flags=0)

說明:把匹配到的字符以列表的形式返回

>>> import re
>>> re.findall('[0-9]{1,3}',"inet addri:10.161.146.134")
['10', '161', '146', '134']   #符合條件的以列表的形式返回

四、re.split(pattern, string, maxsplit=0, flags=0)

說明:匹配到的字符被當作列表分割符

>>> import re
>>> re.split('\.',"inet addri:10.161.146.134")
['inet addri:10', '161', '146', '134']

五、re.sub(pattern, repl, string, count=0, flags=0)

說明:匹配字符並替換

>>> import re
>>> re.sub('\.','-',"inet addri:10.161.146.134")
'inet addri:10-161-146-134'  #默認所有替換
 
>>> re.sub('\.','-',"inet addri:10.161.146.134",count=2)
'inet addri:10-161-146.134'  #用count控制替換次數

 六、finditer(pattern, string)

說明:返回迭代器

>>> import re
>>> re.finditer('addr',"inet addr:10.161.146.134")
<callable_iterator object at 0x00000000030C4BE0>  #返回一個迭代器

2、經常使用方法

一、group([group1, ...])

說明:得到一個或多個分組截獲的字符串;指定多個參數時將以元組形式返回。group1可使用編號也可使用別名;編號0表明整個匹配的子串;不填寫參數時,返回group(0);沒有截獲字符串的組返回None;截獲了屢次的組返回最後一次截獲的子串。

>>> import re
>>> a = re.search('addr',"inet addr:10.161.146.134")
>>> a.group()
'addr'
>>> a.group(0)
'addr'

二、groups(default=None)

說明:以元組形式返回所有分組截獲的字符串。至關於調用group(1,2,…last)。default表示沒有截獲字符串的組以這個值替代,默認爲None。這個要跟分組匹配結合起來使用'(...)'

>>> import re
>>> a = re.search("(\d{2})(\d{2})(\d{2})(\d{4})","320922199508083319") #一個小括號表示一個組,有4個括號,就是4個組
>>> a.groups()
('32', '09', '22', '1995')

 三、groupdict(default=None)

說明:返回以有別名的組的別名爲鍵、以該組截獲的子串爲值的字典,沒有別名的組不包含在內。default含義同上。這個是跟另一個分組匹配結合起來用的,即:'(?P<name>...)'

>>> import re
>>> a = re.search("(?P<province>[0-9]{4})(?P<city>[0-9]{2})(?P<birthday>[0-9]{4})","371481199306143242")
#如下兩種狀況獲取的值都是同樣的
>>> a.groupdict()
{'birthday': '1993', 'city': '81', 'province': '3714'}
>>> a.groupdict("city")
{'birthday': '1993', 'city': '81', 'province': '3714'}

 四、span([group])

說明:返回(start(group), end(group))

>>> import re
>>> a = re.search('addr',"inet addr:10.161.146.134")
>>> a.group()
'addr'
>>> a.span() #獲取'addr'在字符串中的開始位置和結束位置
(5, 9)

 五、start([group])

說明:返回指定的組截獲的子串在string中的起始索引(子串第一個字符的索引),group默認值爲0。

>>> import re
>>> a = re.search('addr',"inet addr:10.161.146.134")
>>> a.group()
'addr'
>>> a.span()
(5, 9)
>>> a.start() #獲取字符串的起始索引
5

 六、end([group])

說明:返回指定的組截獲的子串在string中的結束索引(子串最後一個字符的索引+1),group默認值爲0。

>>> import re
>>> a = re.search('addr',"inet addr:10.161.146.134")
>>> a.group()
'addr'
>>> a.span()
(5, 9)
>>> a.end()  #獲取string中的結束索引
9

七、compile(pattern[, flags])

說明:根據包含正則表達式的字符串建立模式對象

>>> import re
>>> m = re.compile("addr") #建立正則模式對象
>>> n = m.search("inet addr:10.161.146.134")  #經過模式對象去匹配
>>> n.group()
'addr'

3、反斜槓的困擾

與大多數編程語言相同,正則表達式裏使用"\"做爲轉義字符,這就可能形成反斜槓困擾。假如你須要匹配文本中的字符"\",那麼使用編程語言表示的正則表達式裏將須要4個反斜槓"\\\\":前兩個和後兩個分別用於在編程語言裏轉義成反斜槓,轉換成兩個反斜槓後再在正則表達式裏轉義成一個反斜槓。Python裏的原生字符串很好地解決了這個問題,這個例子中的正則表達式可使用r"\\"表示。一樣,匹配一個數字的"\\d"能夠寫成r"\d"。有了原生字符串,你不再用擔憂是否是漏寫了反斜槓,寫出來的表達式也更直觀。

>>> import re
>>> a = re.split("\\\\","C:\ \zhangqigao\yhd_settings")
>>> a
['C:', ' ', 'zhangqigao', 'yhd_settings']
 
>>> re.findall('\\','abc\com')
Traceback (most recent call last)
  
>>> re.findall('\\\\','abc\com')
['\\']
 
>>> re.findall(r'\\','abc\com')
['\\']

4、其餘匹配模式

一、re.I(re.IGNORECASE)

說明:忽略大小寫(括號內是完整的寫法,下同)

>>> import re
>>> a = re.search('addr',"inet Addr:10.161.146.134",flags=re.I)
>>> a.group()
'Addr'  #忽略大小寫

 二、re.M(MULTILINE)

說明:多行模式,改變'^'和'$'的行爲,詳細請見第2點

>>> import re
>>> a = re.search('^a',"inet\naddr:10.161.146.134",flags=re.M)
>>> a.group()
'a'

 三、re.S(DOTALL)

說明:點任意匹配模式,改變'.'的行爲

>>> import re
>>> a = re.search('.+',"inet\naddr:10.161.146.134",flags=re.S)
>>> a.group()
'inet\naddr:10.161.146.134'
相關文章
相關標籤/搜索