1. 程式人生 > >Python正則表示式--Re庫的基本使用

Python正則表示式--Re庫的基本使用

1 正則表示式(regular expression ,RE)

概念:正則表示式(通項公式)是用來簡潔表達一組字串的表示式。優勢是簡潔,一行勝千言。

應用:字串匹配。

1.1 正則表示式的語法

正則表示式語法由字元和操作符組成。

表1:正則表示式的常用操作符

操作符

說明

例項

.

表示任何單個字元

[  ]

字符集,對單個字元給出取值範圍

[ab]表示a、b,[a-z]表示a到z單個字元

[^  ]

非字符集,對單個字元給出排除範圍

[^abc]表示非a或b或c的單個字元

*

前一個字元0次或無限次擴充套件

abc* 表示ab、abc、abcc、abccc等

+

前一個字元1次或無限次擴充套件

abc+ 表示abc、abcc、abccc等

?

前一個字元0次或1次擴充套件

abc? 表示ab、abc

|

左右表示式任意一個

abc|def 表示abc、def

{m}

擴充套件前一個字元m次

ab{2}c表示abbc

{m,n}

擴充套件前一個字元m至n次(含n)

ab{1,2}c表示abc、abbc

^

匹配字串開頭

^abc表示abc且在一個字串的開頭

$

匹配字串結尾

abc$表示abc且在一個字串的結尾

( )

分組標記,內部只能使用| 操作符

(abc)表示abc,(abc|def)表示abc、def

\d

數字,等價於[0‐9]

\w

單詞字元,等價於[A‐Za‐z0‐9_]

1.2 正則表示式例項
正則表示式				對應字串
P(Y|YT|YTH|YTHO)?N	         	'PN'、'PYN'、'PYTN'、'PYTHN'、'PYTHON'
PYTHON+					'PYTHON'、'PYTHONN'、'PYTHONNN' …
PY[TH]ON				'PYTON'、'PYHON'
PY[^TH]?ON				'PYON'、'PYaON'、'PYbON'、'PYcON'…
PY{:3}N					'PN'、'PYN'、'PYYN'、'PYYYN'
經典正則表示式例項

^[A-Za-z]+$				#由26個字母組成的字串
^[A-Za-z0-9]+$				#由26個字母和數字組成的字串
^-?\d+$					#整數形式的字串
^[0-9]*[1-9][0-9]*$			#正整數形式的字串
[1-9]\d{5}				#中國境內郵政編碼,6位
[\u4e00-\u9fa5]			        #匹配中文字元
\d{3}‐\d{8}|\d{4}‐\d{7}	        #國內電話號碼,010-68913536

例項:匹配IP地址的正則表示式 IP地址字串形式的正則表示式(IP地址分4段,每段0‐255)

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

精確寫法0‐99: [1‐9]?\d
100‐199: 1\d{2}
200‐249: 2[0‐4]\d
250‐255: 25[0‐5]

(([1‐9]?\d|1\d{2}|2[0‐4]\d|25[0‐5]).){3}([1‐9]?\d|1\d{2}|2[0‐4]\d|25[0‐5])

2 Re庫的基本使用

Re庫是Python的標準庫,主要用於字串匹配。

呼叫方式:import re

re庫採用raw string型別表示正則表示式,表示為:r'text'

例如:r'[1‐9]\d{5}'
    r'\d{3}‐\d{8}|\d{4}‐\d{7}'

raw string是不包含對轉義符再次轉義的字串。

2.1 Re庫主要功能函式

表2:Re庫主要功能函式

函式

說明

re.search()

在一個字串中搜索匹配正則表示式的第一個位置,返回match物件

re.match()

從一個字串的開始位置起匹配正則表示式,返回match物件

re.findall()

搜尋字串,以列表型別返回全部能匹配的子串

re.split()

將一個字串按照正則表示式匹配結果進行分割,返回列表型別

re.finditer()

搜尋字串,返回一個匹配結果的迭代型別,每個迭代元素是match物件

re.sub()

在一個字串中替換所有匹配正則表示式的子串,返回替換後的字串


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

∙ pattern : 正則表示式的字串或原生字串表示

∙ string : 待匹配字串

∙ flags : 正則表示式使用時的控制標記

常用標記 說明

re.I re.IGNORECASE 忽略正則表示式的大小寫,[A‐Z]能夠匹配小寫字元

re.M re.MULTILINE 正則表示式中的^操作符能夠將給定字串的每行當作匹配開始

re.S re.DOTALL 正則表示式中的.操作符能夠匹配所有字元,預設匹配除換行外的所有字元

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

∙ pattern : 正則表示式的字串或原生字串表示

∙ repl : 替換匹配字串的字串

∙ string : 待匹配字串

∙ count : 匹配的最大替換次數

∙ flags : 正則表示式使用時的控制標記

其他函式引數的含義基本相同,此處不再詳細介紹。

2.2 Re庫的兩種用法

2.2.1 函式式用法:一次性操作

rst = re.search(r'[1‐9]\d{5}', 'BIT 100081')

2.2.2 面向物件用法:編譯後的多次操作

編譯:將符合正則表示式語法的字串轉換成正則表示式特徵。

pat = re.compile(r'[1‐9]\d{5}')

rst = pat.search('BIT 100081')

面向物件用法:編譯後的多次操作

兩種用法等價

2.3 Re庫的Match物件

Match物件是一次匹配的結果,包含匹配的很多資訊。

Match物件的屬性和方法

屬性

說明

方法

說明

.string

待匹配的文字

.group(0)

獲得匹配後的字串

.re

匹配時使用的patter物件(正則表示式)

.start()

匹配字串在原始字串的開始位置

.pos

正則表示式搜尋文字的開始位置

.end()

匹配字串在原始字串的結束位置

.endpos

正則表示式搜尋文字的結束位置

.span()

返回(.start(), .end())


2.4 Re庫的貪婪匹配和最小匹配

2.4.1 貪婪匹配

例項:

>>> match = re.search(r'PY.*N', 'PYANBNCNDN')

>>> match.group(0)

'PYANBNCNDN'

Re庫預設採用貪婪匹配,即輸出匹配最長的子串。

2.4.2 最小匹配

例項:

>>> match = re.search(r'PY.*?N', 'PYANBNCNDN')

>>> match.group(0)

'PYAN'

只要長度輸出可能不同的,都可以通過在操作符後增加?變成最小匹配。

其他操作符還包括:*?、+?、??、{m,n}?

例項:淘寶商品比價定向爬蟲

目標:獲取淘寶搜尋頁面的資訊,提取其中的商品名稱和價格

理解:
     淘寶的搜尋介面
翻頁的處理


搜尋介面和翻頁的URL對應屬性
步驟1:提交商品搜尋請求,迴圈獲取頁面

步驟2:對於每個頁面,提取商品名稱和價格資訊

步驟3:將資訊輸出到螢幕上

原始碼如下所示:

import requests
import re
 
def getHTMLText(url):
    try:
        r = requests.get(url, timeout=30)
        r.raise_for_status()
        r.encoding = r.apparent_encoding
        return r.text
    except:
        return ""
        
def parsePage(ilt, html):
    try:
        #以列表型別返回全部能匹配的子串
        plt = re.findall(r'\"view_price\"\:\"[\d\.]*\"',html)
        #正則表示式的最小匹配
        tlt = re.findall(r'\"raw_title\"\:\".*?\"',html)
        for i in range(len(plt)):
            price = eval(plt[i].split(':')[1])
            title = eval(tlt[i].split(':')[1])
            ilt.append([price , title])
    except:
        print("出現異常")
 
def printGoodsList(ilt):
    tplt = "{:4}\t{:8}\t{:16}"
    print(tplt.format("序號", "價格", "商品名稱"))
    count = 0
    for g in ilt:
        count = count + 1
        print(tplt.format(count, g[0], g[1]))
         
def main():
    goods = '水杯'
    depth = 3
    start_url = 'https://s.taobao.com/search?q=' + goods
    infoList = []
    for i in range(depth):
        try:
            url = start_url + '&s=' + str(44*i)
            html = getHTMLText(url)
            parsePage(infoList, html)
        except:
            continue
    printGoodsList(infoList)
     
main()

輸出結果如下圖所示: