1. 程式人生 > >16、正則表達式

16、正則表達式

影響 專業 想要 20億 小型 取消 最好 法語 完全匹配

正則表達式

目標

  • 掌握正則表達式的規則

案例

  • 一個小爬蟲

簡介

  • 正則表達式(或re)是一種小型的、高度專業化的編程語言,(在python中)它內嵌在python中,並通過re模塊實現
    • 可以為想要匹配的相應字符串集指定規則
    • 該字符集可能包含英文語句、e-mail地址、命令或任何你想搞定的東西
    • 可以問諸如“這個字符串匹配該模式嗎”
    • “在這個字符串中是否有部分匹配該模式呢?”
    • 你也可以使用re以各種試來修改或分割字符串
  • 正則表達式模式被編譯成一系列的字節碼,然後由C編寫的匹配引擎執行
  • 正則表達式語言相對小型和受限(功能有限)
    • 並非所有字符串處理都能用正則表達式完成

字符匹配

  • 普通字符
    • 大多數字母和數字一般都會和自身匹配
    • 如正則表達式test會和字符串"test"完全匹配
  • 元字符

    .   ^   $   *   +   ?   {}  []  \   |   ()
    • []
      • 常用來指定一個字符集:[abc] [a-z]
      • 元字符在字符集中不起作用:[akm$]
      • 補集匹配不在區間範圍內的字符:[^5]

        import re
        
        regExp = r't[0-9]p'
        print re.findall(regExp, 't1p t2p')
    • ^
      • 匹配行首。除非設置MULTILINE標誌,它只是匹配字符串的開始。在MULTILINE模式裏,它也可以匹配字符串中的每個換行。
    • $
      • 匹配行尾,行尾被定義為要麽是字符串尾,要麽是一個換行字符後面的任何位置。
    • \
      • 反斜杠後面可以加不同的字符以表示不同特殊意義
      • 也可以用於取消所有的元字符:\[\\

        \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]
    • 重復
      • 正則表達式第一功能是能夠匹配不定長的字符集,另一個功能就是可以指定正則表達式的一部分的重復次數。
    • *
      • 指定前一個字符可能被匹配零次或更多次,而不是只有一次。匹配引擎會試著重復盡可能多的次數(不超過整數界定範圍,20億)
    • +
      • 表示匹配一次或更多次
      • 註意和+之間的不同:匹配零或更多次,所以可以根本不出現,而+則要求至少出現一次
    • ?
      • 匹配一次或零次,你可以認為它用於標識某事物是可選的
    • {m,n}
      • 其中mn是十進制整數。該限定符的意思是至少有m個重復,至多到n個重復
      • 忽略m會認為下邊界是0,而忽略n的結果將是上邊界為無窮大(實現上是20億)
      • {0,}等同於*{1,}等同於+,而{0,1}則與?相同。如果可以的話,最好使用*+?

使用正則表達式

  • re模塊提供了一個正則表達式引擎的接口,可以讓你將REstring編譯成對象並用它們來進行匹配
  • 編譯正則表達式

    >>> import re
    >>> p = re.compile('ab*')
    >>> print p
    <_sre.SRE_Pattern object at 0x00000000004D1CA8>
  • re.compile()也可以接受可選擇的標誌參數,常用來實現不同的特殊功能和語法變更

    p = re.compile('ab*', re.IGNORECASE)

反斜杠的麻煩

  • 字符串前加"r"反斜杠就不會被任何特殊方式處理
字符 階段
\section 要匹配的字符串
\section 為re.compile取消反斜杠的特殊意義
"\\section" 為"\section"的字符串實值(string literals)取消反斜杠的特殊意義

執行匹配

  • ‘RegexObject‘實例有一些方法和屬性,完整的列表可查閱Python Library Reference
方法/屬性 作用
match() 決定RE是否在字符串剛開始的位置匹配
search() 掃描字符串,找到這個RE匹配的位置
findall() 找到RE匹配的所有子串,並把它們作為一個列表返回
finditer() 找到RE匹配的所有子串,並把它們作為一個叠代器返回
    如果沒有匹配到的話,match()和search()將返回None。
    如果成功的話,就會返回一個'MatchObject'實例。
  • MatchObject實例方法
方法/屬性 作用
group() 返回被RE匹配的字符串
start() 返回匹配開始的位置
end() 返回匹配結束的位置
span() 返回一個元組包含匹配(開始,結束)的位置
  • 實際程序中,最常見的作法是將‘MatchObject‘保存在一個變量裏,然後檢查它是否為None

    p = re.compile('ab*', re.I)
    m = p.match('aaaabcccccabcc')
    
    if m:
        print 'Match found : ', m.group()
    else:
        print 'No match'

模塊級函數

  • re模塊也提供了頂級函數調用如match()、search()、sub()、subn()、split()、findall()
  • 查看模塊的所有屬性和方法: dir(re)

編譯標誌-flags

標誌 含義
DOTALL, S 使.匹配包括換行在內的所有字符
IGNORECASE, I 使匹配對大小寫不敏感
LOCALE, L 做本地化識別(local-aware)匹配.法語等
MULTILINE, M 多行匹配,影響^和$
VERBOSE, X 能夠使用REs的verbose狀態,使之被組織得更清晰易懂
charref = re.compile(r"""
(
[0-9]+[^0-9]    #Decimal form
| 0[0-7]+[^0-7] #Octal form
| x[0-9a-fA-F]+[^0-9a-fA-F] #Hexadecimal form
)
""", re.VERBOSE)

分組()

email = r"\w+@\w+(\.com|\.cn)"

一個小爬蟲

  • 下載貼吧或空間中所有圖片

    import re
    import urllib
    
    def getHtml(url):
        page = urllib.urlopen(url)
        html = page.read()
        return html
    
    def getImg(html):
        reg = r'src="(.*?\.jpg)" width'
        imgre = re.compile(reg)
        imglist = re.findall(imgre, html)
        x = 0
        for imgurl in imglist:
            urllib.urlretrieve(imgurl, '%s.jpg' % x)
            x++
    
    getImg(getHtml(url))

16、正則表達式