python--經常使用模塊之正則

引自:http://www.cnblogs.com/haiyan123/p/7298967.htmlhtml

認識模塊python

常見模塊分類 git

正則表達式正則表達式

re模塊app

re模塊和正則表達式的關係dom

collections模塊ide

 

1、認識模塊

    什麼是模塊:一個模塊就是一個包含了python定義和聲明的文件,文件名就是加上.py的後綴,但其實import加載的模塊分爲四個通用類別 :函數

    1.使用python編寫的代碼(.py文件)

    2.已被編譯爲共享庫二和DLL的C或C++擴展

    3.包好一組模塊的包

    4.使用C編寫並鏈接到python解釋器的內置模塊 

    爲什麼要使用模塊?工具

    若是你想退出python解釋器而後從新進入,那麼你以前定義的函數或變量都將丟失,所以咱們一般將程序寫到文件中以便永久保存下來,須要時,就經過python test.py 方式去執行,此時test.py被稱爲腳本script。

    隨着程序的發展,功能愈來愈多,爲了方便管理,咱們一般將文件分紅一個個的文件,這樣作程序的結構更清晰,方便管理。這時咱們不只僅能夠吧這些文件當作腳本去執行,還能夠把它們當作模塊來導入到其餘模塊中,實現了功能的重複利用。

 

2、常見模塊分類

  經常使用模塊1、post

      collocations 模塊

      時間模塊

      random模塊

      os模塊

      sys模塊

      序列化模塊

      re模塊 

  經常使用模塊二:這些模塊和麪向對象有關

      hashlib模塊

      configparse模塊

      logging模塊 

3、正則表達式

像咱們日常見的那些註冊頁面啥的,都須要咱們輸入手機號碼吧,你想咱們的電話號碼也是有限定的吧(手機號碼一共11位,而且只以13,14,15,17,18開頭的數字這些特色)若是你的輸入有誤就會提示,那麼實現這個程序的話你以爲用While循環so easy嘛,那麼咱們來看看實現的結果。

while True:
    phone_number=input('請輸入你的電話號碼:')
    if len(phone_number)==11 and phone_number.isdigit()\
        and (phone_number.startswith('13')\
        or phone_number.startswith('14') \
        or phone_number.startswith('15') \
        or phone_number.startswith('17') \
        or phone_number.startswith('18')):
        print('是合法的手機號碼')
    else:
        print('不是合法的手機號碼')
判斷手機號碼是否合法

看到這個代碼,雖然說理解很容易,可是我還有更簡單的方法。那咱們一塊兒來看看吧。

import re
phone_number=input('請輸入你的電話號碼:')
if re.match('^(13|14|15|17|18)[0-9]{9}$',phone_number):
    '''^這個符號表示的是判斷是否是以13|14|15|17|18開頭的,
    [0-9]: []表示一個字符組,能夠表示0-9的任意字符
    {9}:表示後面的數字重複九次
    $:表示結束符
    '''
    print('是合法的手機號碼')
else:
    print('不是合法的手機號碼')
判斷手機號碼輸入是否合法

你們可能都覺的第一種方法更簡單吧,可是若是我讓你從整個文件中匹配出全部的手機號碼,你能用python寫出來嗎?可是導入re模塊和利用正則表達式就能夠解決這一個問題了。

那麼什麼是正則呢?

  首先你要知道的是,談到正則,就只和字符串相關了。在線測試工具 http://tool.chinaz.com/regex/

好比你要用‘1’去匹配‘1’,或者用‘2’去匹配‘2’,直接就能夠匹配上。

字符組:[字符組]
在同一位置可能出現的各類字符組成了一個字符組,在正則表達式中用[]表示
字符分爲不少類,好比數字,字母,標點等。
假如你如今要求一個位置‘只能出現一個數字’,那麼這個位置上的字符只能是0、一、二、3.......9這是個數之一。

字符組:

字符:

量詞:

.^$

*+?{}

注意:前面的*,+,?等都是貪婪匹配,也就是儘量多的匹配,後面加?就變成了非貪婪匹配,也就是惰性匹配。

貪婪匹配:

幾個經常使用的貪婪匹配

*?;重複任意次,但儘量少重複 +?:重複一次或更屢次,但儘量少重複
??:重複0次或1次,但儘量少重複
{n,m}:重複n到m次,但儘量少重複
{n,}: 重複n次以上,但儘量少重複

.*?的用法:

.是任意字符
*是取0到無限長度
?是非貪婪模式
和在一塊兒就是取儘可能少的任意字符,通常不會這麼單獨寫,大多用在:
.*?x
意思就是取前面任意長度的字符,直到一個x出現

字符集:

分組()與或|[^]:

(1)^[1-9]\d{13,16}[0-9x]$     #^以數字0-9開始,
                                \d{13,16}重複13次到16次
                                $結束標誌
上面的表達式能夠匹配一個正確的身份證號碼
 
(2)^[1-9]\d{14}(\d{2}[0-9x])?$     
#?重複0次或者1次,當是0次的時候是15位,是1的時候是18位
3)^([1-9]\d{16}[0-9x]|[1-9]\d{14})$
#表示先匹配[1-9]\d{16}[0-9x]若是沒有匹配上就匹配[1-9]\d{14}                
舉個例子,好比html源碼中有<title>xxx</title>標籤,用之前的知識,咱們只能肯定源碼中的<title>和</title>是固定不變的。所以,若是想獲取頁面標題(xxx),充其量只能寫一個相似於這樣的表達式:<title>.*</title>,而這樣寫匹配出來的是完整的<title>xxx</title>標籤,並非單純的頁面標題xxx。

       想解決以上問題,就要用到斷言知識。

       在講斷言以前,讀者應該先了解分組,這有助於理解斷言。

       分組在正則中用()表示,根據小菜理解,分組的做用有兩個:

 

       n  將某些規律當作是一組,而後進行組級別的重複,能夠獲得意想不到的效果。

       n  分組以後,能夠經過後向引用簡化表達式。

 

 

       先來看第一個做用,對於IP地址的匹配,簡單的能夠寫爲以下形式:

       \d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}

       但仔細觀察,咱們能夠發現必定的規律,能夠把.\d{1,3}當作一個總體,也就是把他們當作一組,再把這個組重複3次便可。表達式以下:

       \d{1,3}(.\d{1,3}){3}

       這樣一看,就比較簡潔了。

      

再來看第二個做用,就拿匹配<title>xxx</title>標籤來講,簡單的正則能夠這樣寫:

       <title>.*</title>

       能夠看出,上邊表達式中有兩個title,徹底同樣,其實能夠經過分組簡寫。表達式以下:

       <(title)>.*</\1>

       這個例子實際上就是反向引用的實際應用。對於分組而言,整個表達式永遠算做第0組,在本例中,第0組是<(title)>.*</\1>,而後從左到右,依次爲分組編號,所以,(title)是第1組。

       用\1這種語法,能夠引用某組的文本內容,\1固然就是引用第1組的文本內容了,這樣一來,就能夠簡化正則表達式,只寫一次title,把它放在組裏,而後在後邊引用便可。

       以此爲啓發,咱們可不能夠簡化剛剛的IP地址正則表達式呢?原來的表達式爲\d{1,3}(.\d{1,3}){3},裏邊的\d{1,3}重複了兩次,若是利用後向引用簡化,表達式以下:

       (\d{1,3})(.\1){3}

       簡單的解釋下,把\d{1,3}放在一組裏,表示爲(\d{1,3}),它是第1組,(.\1)是第2組,在第2組裏經過\1語法,後向引用了第1組的文本內容。

       通過實際測試,會發現這樣寫是錯誤的,爲何呢?

       小菜一直在強調,後向引用,引用的僅僅是文本內容,而不是正則表達式!

       也就是說,組中的內容一旦匹配成功,後向引用,引用的就是匹配成功後的內容,引用的是結果,而不是表達式。

       所以,(\d{1,3})(.\1){3}這個表達式實際上匹配的是四個數都相同的IP地址,好比:123.123.123.123。

      

       至此,讀者已經掌握了傳說中的後向引用,就這麼簡單。
對於分組的理解

分組命名:語法(?p<name>)注意先命名,後正則

import  re
import re
ret=re.search('<(\w+)>\w+<(/\w+)>','<h1>hello</h1>')   
print(ret.group())
# 給分組起個名字。就用下面的分組命名,上面的方法和下面的分組命名是同樣的,只不過就是給命了個名字
ret=re.search('<(?P<tag_name>\w+)>\w+</(?P=tag_name)>','<h1>hello</h1>')

#(?P=tag_name)就表明的是(\w+)  
print(ret.group()) # 瞭解(和上面的是同樣的,是上面方式的那種簡寫) 
ret=re.search(r'<(\w+)>\w+</\1>','<h1>hello</h1>') 
print(ret.group(1))

轉義符:

4、re模塊

# 1.re模塊下的經常使用方法
# 1.findall方法
import re
ret = re.findall('a','eva ang  egons')
# #返回全部知足匹配條件的結果,放在列表裏
print(ret)

# 2.search方法
# 函數會在字符串中查找模式匹配,只會找到第一個匹配而後返回
# 一個包含匹配信息的對象,該對象經過調用group()方法獲得匹配的
# 字符串,若是字符串沒有匹配,則報錯
ret = re.search('s','eva ang  egons')#找第一個
print(ret.group())


# 3.match方法
print(re.match('a','abc').group())
#同search,只從字符串開始匹配,而且guoup才能找到


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


# 5.sub方法
print(re.sub('\d','H','eva3sdf4ahi4asd45',1))
# 將數字替換成'H',參數1表示只替換一個


# 6.subn方法
print(re.subn('\d','H','eva3sdf4ahi4asd45'))
#將數字替換成’H‘,返回元組(替換的結果,替換了多少次)


# 7.compile方法
obj = re.compile('\d{3}')#將正則表達式編譯成一個正則表達式對象,規則要匹配的是三個數字
print(obj)
ret = obj.search('abc12345eeeee')#正則表達式對象調用search,參數爲待匹配的字符串
print(ret.group()) #.group一下就顯示出結果了

# 8.finditer方法
ret = re.finditer('\d','dsf546sfsc')#finditer返回的是一個存放匹配結果的迭代器
# print(ret)#<callable_iterator object at 0x00000000021E9E80>
print(next(ret).group())#查看第一個結果
print(next(ret).group())#查看第二個結果
print([i.group() for i in ret] )#查看剩餘的左右結果
re模塊相關的方法
import re
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']
findall的優先級查詢
ret = re.split('\d+','eva123dasda9dg')#按數字分割開了
print(ret) #輸出結果:['eva', 'dasda', 'dg']

ret = re.split('(\d+)','eva123dasda9dg')
print(ret) #輸出結果:['eva', '123', 'dasda', '9', 'dg']
# 
# 在匹配部分加上()以後和不加括號切出的結果是不一樣的,
# 沒有括號的沒有保留所匹配的項,可是有括號的卻可以保留了
# 匹配的項,這個在某些須要保留匹配部分的使用過程是很是重要的
split的優先級查詢

5、re模塊和正則表達式的關係

re模塊和正則表達式沒有一點毛線關係。re模塊和正則表達式的關係相似於time模塊和時間的關係,你沒有學習python以前,也不知道有一個time模塊,可是你已經認識時間了呀,12:30就表示中午十二點半。時間有本身的格式,年月日時分秒,已成爲一種規則。你早就牢記於心了,time模塊只不過是python提供給咱們的能夠方便咱們操做時間的一個工具而已。

6、collections模塊

在內置數據類型(dict,list,set,tuple)的基礎上,collections 模塊還提供了幾個額外的數據類型:

1.namedtuple:生成可使用名字來訪問元素內容的tuple

2.deque:雙向隊列(兩頭均可進可出,可是不能取中間的值),能夠快速的從另一側追加和推出對象

3.Counter:計數器,主要用來計數

4.OrderedDict:有序字典

5.defaultdict:帶有默認值的字典

 

namedtuple:

  咱們知道tuple能夠表示不變集合,例如,一個點的二維座標就能夠表示成:p=(1,2)

可是,看到(1,2),很難看出這個tuple是用來表示座標的。

那麼,咱們的namedtuple就能用上了。 

namedtuple('名稱',‘屬性list’)

from  collections import namedtuple
point = namedtuple('point',['x','y'])
p = point(1,2)
print(p.x,p.y)、<br><br><br>
Circle = namedtuple('Circle', ['x', 'y', 'r'])#用座標和半徑表示一個圓

deque

單向隊列<br># import queue  #隊列模塊
# q = queue.Queue()
# q.put(10)
# q.put(20)
# q.put(30)
# # 10 20 30
# print(q.get())
# print(q.get())
# print(q.get())
# print(q.get())

deque是爲了高效實現插入和刪除操做的雙向隊列,適用於隊列和棧

from collections import deque
q = deque(['a','b','c'])
q.append('ee')#添加元素
q.append('ff')
q.append('qq')
print(q)
q.appendleft('www')#從左邊添加
print(q)
 
 
q.pop() #刪除元素
q.popleft() #從左邊刪除元素
print(q)

OrderedDict

使用字典時,key是無序的。在對字典作迭代時,咱們沒法肯定key的順序。若是要保持key的順序,能夠用OrderedDict

from collections import OrderedDict
d = {'z':'qww','x':'asd','y':'asd','name':'alex'}
print(d.keys()) #key是無序的

 

od = OrderedDict([('a', 1), ('b', 2), ('c', 3)]) print(od)# OrderedDict的Key是有序的 <br>OrderedDict([('a', 1), ('b', 2), ('c', 3)])<br><br><br>

 

注意,OrderedDict的Key會按照插入的順序排列,不是Key自己排序:
od = OderedDict ()

od['z']=1

od['y']=2

od['x']=3

print(od.keys())   #按照插入額key的順序返回

defaultdict

d = {'z':'qww','x':'asd','y':'asd','name':'alex'}
print(d.keys())
from  collections import defaultdict
values = [11,22,33,44,55,66,77,88,99]
my_dict = defaultdict(list)
for v in values:
    if v>66:
        my_dict['k1'].append(v)
    else:
        my_dict['k2'].append(v)
print(my_dict)
找大於66和小於66的
from collections import defaultdict
dd = defaultdict(lambda: 'N/A')
dd['key1'] = 'abc'
print(dd['key1']) # key1存在

print(dd['key2']) # key2不存在,返回默認值
defaultdict

Counter

Counter類的目的是用來跟蹤值出現的次數。它是一個無序的容器類型,以字典的鍵值對形式存儲,其中元素做爲key,其計數做爲value。計數值能夠是任意的Interger(包括0和負數)。Counter類和其餘語言的bags或multisets很類似。

from collections import Counter
c = Counter('abcdeabcdabcaba')
print(c)
# 輸出:Counter({'a': 5, 'b': 4, 'c': 3, 'd': 2, 'e': 1})
其餘詳細內容 http://www.cnblogs.com/Eva-J/articles/7291842.html
 
相關文章
相關標籤/搜索