day5模塊學習--re正則模塊

1. 正則表達式基礎html

1.1. 簡單介紹python

    正則表達式並非Python的一部分。正則表達式是用於處理字符串的強大工具,擁有本身獨特的語法以及一個獨立的處理引擎,效率上可能不如str自帶的方法,但功能十分強大。得益於這一點,在提供了正則表達式的語言裏,正則表達式的語法都是同樣的,區別只在於不一樣的編程語言實現支持的語法數量不一樣;但不用擔憂,不被支持的語法一般是不經常使用的部分。若是已經在其餘語言裏使用過正則表達式,只須要簡單看一看就能夠上手了。正則表達式

    下圖展現了使用正則表達式進行匹配的流程:  http://www.cnblogs.com/huxi/archive/2010/07/04/1771073.html
編程

   

 

    正則表達式的大體匹配過程是:依次拿出表達式和文本中的字符比較,若是每個字符都能匹配,則匹配成功;一旦有匹配不成功的字符則匹配失敗。若是表達式中有量詞或邊界,這個過程會稍微有一些不一樣,但也是很好理解的,看下圖中的示例以及本身多使用幾回就能明白。編程語言

    下圖列出了Python支持的正則表達式元字符和語法:工具

   

    1.」.「匹配任意除換行符之外的字符編碼

    >>> string = "abafsdafd\nafdasfd"         #包含換行符
  >>> string1 = "adfasdfadfasdfwer12345656耿"     #不包含換行符
  >>> import re  
  >>> m = re.search(".+",string)           #驗證是否能夠匹配換行符
  >>> m.group()
  'abafsdafd'
spa

    >>> n = re.search(".+",string1)
  >>> n.group()
  'adfasdfadfasdfwer12345656耿'
    從上面輸出結果能夠看出,」.「是匹配任意除了換行符的字符。遇到"\n"換行符即終止匹配。
.net

    2.」\"轉義字符code

    轉義字符,使後一個字符改變原來的意思。若是字符串中有*號須要匹配,可使用\*或者字符集[*],"a\.c"表明匹配a.c  "a\\c"表明匹配a\c

    >>> str_num = "22.567979mafdasdf"
  >>> m = re.search("\d+\.\d+",str_num)
  >>> m.group()
  '22.567979'
    咱們知道,"."在python中表明的含義是除了"\n"以外的全部字符,若是這裏不進行轉義的話,匹配出來的就是任意非"\n"字符,所以要使用"\"進行轉義。

    >>> string = "dfafdasfd\fafdasfda"
  >>> string
  'dfafdasfd\x0cafdasfda'
    在python中,若是字符串中包含"\",有時候會顯示不出來,或者修改後面的內容,把別人改變了,這個不知道在Linux平臺上是怎麼回事。

    3.[...]字符集(字符類)   
    [...]:字符集(字符類)對應的位置能夠是字符集中任意字符。字符集中的字符能夠逐個列出[0,1,2,3,4,5,6,7,8,9],也能夠給出範圍[0-9]。第一個字符集若是是^表示取反,如[^abc]表示不是abc的其餘字符。

    全部的特殊字符在字符集中都失去其原有的特殊意義。在字符集中若是要使用]、或^,能夠在前面加上"\"反斜槓,或把]\、-放在第一個字符,把^放在非第一個字符。

    >>> string = "dafdafdasf[adfas^fad"

    >>> m = re.search("[a-z]+\[",string)
  >>> m.group()
  'dafdafdasf['
    從上面腳本能夠看出,若是要匹配[要在前面加上"\"轉義字符。

    >>> m = re.search("\w+[[]",string)      (1)在字符集中匹配"["
  >>> m.group()
  'dafdafdasf['
    >>> n = re.search("w+[\[]",string)      (2)轉義匹配,驗證在字符集中匹配[是否須要加[\]
  >>> n.group()
  Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
  AttributeError: 'NoneType' object has no attribute 'group'
    在字符集中若是要使用]、或^,能夠在前面加上"\"反斜槓,或把]\、-放在第一個字符,把^放在非第一個字符。
    預約義字符集

    1.\d數字

    >>> m = re.search("\d",string)
  >>> m.group()
  '1'
    \d是匹配數字,等價於[0-9]
    2.\D非數字       等價於[^\d]

    >>> string = "dfaMNA12581耿fa"
  >>> m = re.search("\D",string)
  >>> m.group()
  'd'
  >>> n = re.search("[^\d]",string)
  >>> n.group()
  'd'

    >>> l = re.search("[^0-9]",string)
  >>> l.group()
  'd'
    從上面能夠看出,「\D」是用來匹配非數字的,匹配除了數字0-9意外的任意字符,等價於[^0-9]或[^\d]
    3.\s空白字符     [<空格>\r\t\n\f\v]

    「\s」是匹配任意非空字符,如[<空格>\r\t\n\f\v]等,實例以下:

    >>> m = re.search("\s+",string)     #\s進行匹配空白字符
  >>> m.group()
  ' \t \n \x0c \x0b \r'
    從上面能夠看出,\s是匹配任意空白字符,如空格、\r、\t、\n、\f、\v等

    4.\S非空白字符     \S與\s正好相反,是匹配任意非空字符。等價於[^\s]匹配任意非空字符

    >>> string = "faMM耿 \t \n \f \v \rDASDF"
    >>> n = re.search("\S+",string)
  >>> n.group()
  'faMM耿'
    從上面能夠看出"\S"是匹配任意非空字符,遇到空的字符即中止了,匹配任意非空字符,"."匹配任意字符,除了換行符以外。

    >>> m = re.search(".+",string)
  >>> m.group()
  'faMM耿 \t '
    從上面看出,「\S」和「.」仍是有差異的,一個是任意非空字符,一個是匹配任意除了"\n"意外任意非空字符。

    5.\w 單詞字符[A-Z0-9a-z_]   
    \w是匹配單詞字符,下面來看下能不能匹配漢字或其餘:

    >>> string = "faMM耿 \t \n \f \v \rDASDF"

    >>> m = re.search("\w+",string)
  >>> m.group()
  'faMM耿'                (1)腳本

    >>> format_string = "fdMM更KKMM長 /大MM \n \tMMKDSI"
  >>> m = re.search("\w+",format_string)
  >>> m.group()
  'fdMM更KKMM長'          (2)腳本

    能夠看出,"\w"是能夠匹配漢字的,不能匹配空格,換行符這些,可是可以匹配漢字。

    6.\W       等價於非單詞字符 [^\w]  

    >>> import re
  >>> string = "naefda曾 LmKDS 1316547\n\t\r@@3$&^$"
  >>> m = re.search("\W+",string)

    >>> m.group()
  ' '

    從上面能夠看出"\W "匹配出來了空,說明" "不是單詞字符,"\W"是匹配非單詞字符。

    數量詞(用在字符或(...)以後)

    1."*"       匹配前一個字符0或無限次       前一個字符

    "*"是匹配前一個字符0或無限次

    >>> import re
  >>> string = "naefda曾 LmKDS 1316547\n\t\r@@3$&^$"
    >>> m = re.search("\w*",string)
  >>> m.group()
  'naefda曾'
  >>> n = re.search("\d*",string)
  >>> n.group()
  ''

    >>> n = re.search("耿",string)
  >>> n
  >>> n.group()
  Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
  AttributeError: 'NoneType' object has no attribute 'group'

    從上面腳本代碼能夠看出,當使用*要查找的字符在開頭的時候就會匹配到,在中間就匹配不到。這種懶惰的匹配方式,若是其餘狀況下匹配不到,則會返回錯誤。

    2.「+」    匹配前一個字符一次或無限次    前一個字符(牢記,只是匹配前面一個)

    >>> import re
  >>> string = "naefda曾 LmKDS 1316547\n\t\r@@3$&^$"
    >>> m = re.search("\w+",string)
  >>> m.group()
  'naefda曾'
  >>> n = re.search("\s+",string)
  >>> n.group()
  ' '
  >>> d = re.search("更",string)
  >>> d.group()
  Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
  AttributeError: 'NoneType' object has no attribute 'group'
    從上面能夠看出,"+"是匹配前一個字符一次或無限次,若是匹配不到,則返回None

    3."?"   匹配前一個字符0次或一次        前一個字符(牢記,只是匹配前面一個)

    >>> import re
  >>> string = "naefda曾 LmKDS 1316547\n\t\r@@3$&^$"
  >>> m = re.search("\w?",string)
  >>> m.group()
  'n'
  >>> n = re.search("f?",string)
  >>> n.group()
  ''
    從上面能夠看出,?是以貪婪的方式進行匹配。?是匹配前一個字符0次或1次。從上面的例子中發現一個問題,即"?"和"*"都是從頭開始進行匹配,若是開頭匹配不到,就返回"",等價於若是使用search()出現」?"和「*」等價於使用match()從頭開始匹配,找不到則不找了,不同的是match()返回的是None,而seach()返回的是""。

    4.{m}   表明匹配前一個字符m次        前一個字符(牢記,只是匹配前面一個)

    >>> import re

    >>> string = "dafMM\n更1134657Qqcd m,l#!"
  >>> m = re.search("\d{4}",string)        #表明匹配數字四次
  >>> m.group()
  '1134'

    >>> n = re.search("\d{10}",string)
  >>> n.group()
  Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
  AttributeError: 'NoneType' object has no attribute 'group'

    從上面能夠看出,若是匹配不到,則返回None;{m}是表明匹配前一個字符m次,要注意在匹配的時候,咱們能夠像下面同樣設定一個匹配區間,這樣就不會出現匹配超標的狀況。

    5.{m,n}    匹配一個字符m次至n次         前一個字符(牢記,只是匹配前面一個)

    m和n能夠省略,如省略m({,n})則匹配0到n次;若省略n({m,}),則匹配m至無限次。

    >>> import re

    >>> string = "dafMM\n更1134657Qqcd m,l#!"

   >>> m = re.search("\d{1,10}",string)
  >>> m.group()
  '1134657'
  >>> n = re.search("\d{,5}",string)
  >>> n.group()
  ''
  >>> d = re.search("\d{4,}",string)
  >>> d.group()
  '1134657'
    從上面能夠看出,{m,n}是匹配在一個範圍內的個數,可是咱們也發現了一個問題,千萬不要讓正則表達式匹配包含0次的狀況,一旦匹配0次,那麼就會出現若是開頭匹配不到以後,就不匹配的狀況,直接返回""。

    *? +? ?? {m,n}?使*,+,?,{m,n}變成非貪婪模式。

    邊界匹配

    1.^  匹配字符串開頭,在多行模式中,匹配第一行的開頭

    >>> import re

    >>> string = "dafMM\n更1134657Qqcd m,l#!"

    >>> m = re.search("^da",string)
  >>> m.group()
  'da'

    開頭匹配,至關於使用match()進行匹配了。

    2.$    匹配字符串末尾,在多行模式中匹配每一行的末尾  

    >>> import re

    >>> string = "dafMM\n更1134657Qqcd m,l#!"

    >>> m = re.search("#!",string)
  >>> m.group()
  '#!'
    "$"是匹配字符串的末尾,無論前面,值匹配末尾是不是要匹配的內容。

    3.\A    僅匹配字符串開頭

    >>> import re

    >>> string = "dafMM\n更1134657Qqcd m,l#!"

    >>> m = re.search("\Adaf",string)
  >>> m.group()
  'daf'
    「\A」是僅匹配字符串開頭,即僅僅從字符串的開頭進行匹配。
    4.\Z    僅匹配字符串末尾

    >>> import re

    >>> string = "dafMM\n更1134657Qqcd m,l#!"

    >>> n = re.search("l#!",string)
  >>> n.group()
  'l#!'
    "\Z"是僅匹配字符串末尾,僅從末尾進行匹配,可能\Z和$的區別就是,$是匹配每行的末尾,而\Z是僅匹配字符串的末尾。

    5.\b   匹配\w和\W之間的字符   

    6.\B    匹配非\w和\W之間的字符 即[^\b]   

    邏輯分組

    1.「|」   表明左右表達式任意匹配一個

    它老是先嚐試匹配左邊的表達式,一旦成功則跳過右邊的表達式。若是|沒有被包含在()中,則它的範圍是整個正則表達式

    >>> import re
  >>> m = re.search("(?P<province>[0-9]{4})(?P<city>[0-9]{2})(?P<birthday>[0-9]{4})","371481199306143242").groupdict()
  >>> m
  {'city': '81', 'birthday': '1993', 'province': '3714'}

    能夠依次分組匹配,生成一個字典,groupdict(),分組匹配,給匹配到的字符串起名字。

1.2. 數量詞的貪婪模式與非貪婪模式

  正則表達式一般用於在文本中查找匹配的字符串。Python裏數量詞默認是貪婪的(在少數語言裏也多是默認非貪婪),老是嘗試匹配儘量多的字符;非貪婪的則相反,老是嘗試匹配儘量少的字符。例如:正則表達式"ab*"若是用於查找"abbbc",將找到"abbb"。而若是使用非貪婪的數量詞"ab*?",將找到"a"。

1.3. 反斜槓的困擾

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

 

1.4. 匹配模式

    正則表達式提供了一些可用的匹配模式,好比忽略大小寫、多行匹配等,這部份內容將在Pattern類的工廠方法re.compile(pattern[, flags])中一塊兒介紹。

2. re模塊     
    2.1. 開始使用re   
    Python經過re模塊提供對正則表達式的支持。使用re的通常步驟是先將正則表達式的字符串形式編譯爲Pattern實例,而後使用Pattern實例處理文本並得到匹配結果(一個Match實例),最後使用Match實例得到信息,進行其餘的操做。 

import re

#將正則表達式編譯成Pattern對象
pattern = re.compile(r'hello')

#使用pattern匹配文本,得到匹配結果,沒法匹配時將返回None
match = pattern.match("hello world!")
if match:
    #使用match得到分組信息
    print(match.group())

 

    上面正則匹配中,首先進行了編譯,編譯成正則格式,而後進行匹配。

    re.compile(strPattern[, flag]):

    這個方法是Pattern類的工廠方法,用於將字符串形式的正則表達式編譯爲Pattern對象。 第二個參數flag是匹配模式,取值可使用按位或運算符'|'表示同時生效,好比re.I | re.M。另外,你也能夠在regex字符串中指定模式,好比re.compile('pattern', re.I | re.M)與re.compile('(?im)pattern')是等價的。
可選值有:

    re模塊還提供了一個方法escape(string),用於將string中的正則表達式元字符如*/+/?等以前加上轉義符再返回,在須要大量匹配元字符時有那麼一點用。

    2.2. Match  
  >>> string = "aafaaMMaaaa"
  >>> m = re.search("aa?",string)
  >>> m.group()
  'aa'
  >>> n = re.search("aaa?",string)
  >>> n.group()
  'aa'
  >>> d = re.search("aaaa?",string)
  >>> d.group()
  'aaaa'
    上面代碼中,"?"的做用是匹配前一個字符,就是這個正則符號前面的那個字符0次或一次。

    正則表達式匹配中文(http://blog.csdn.net/tao_627/article/details/51019972)

    import re
  name = "ge耿長學164——///大師傅"
  # name = name.encode('utf-8')
  d = re.search(u"([\u4e00-\u9fa5]+)",name)
  print(d.group())

    unicode中中文的編碼爲/u4e00-/u9fa5

    上面的正則表達式u"([\u4e00-\u9fa5]+)"就是用來匹配中文字符的,

    匹配非中文字符集以下:

    import re
  name = "ge耿長學164——///大師傅"
  # name = name.encode('utf-8')
  d = re.search(u"([^\u4e00-\u9fa5]+)",name)
  print(d.group())

    只需在正則表達式裏面加上^,非的意思,就是匹配中文意外的其餘字符。

相關文章
相關標籤/搜索