五十八、Python中的正則表達式

@Author:Runsen

@Date:2019/03/03


作者介紹:Runsen目前大三下學期,專業化學工程與工藝,大學沉迷日語,Python, Java和一系列數據分析軟件。導致翹課嚴重,專業排名中下。.在大學60%的時間,都在CSDN。決定今天比昨天要更加努力。

@updated Date:2020/5/29

正則表達式

正則表達式是一個特殊的字符序列,由普通字符和元字符組成。元字符能幫助你方便的檢查一個字符串是否與某種模式匹配。

正則表達式應用的場景也非常多。常見的比如:搜索引擎的搜索、爬蟲結果的匹配、文本數據的提取等等都會用到,所以掌握甚至精通正則表達式是一個硬性技能,非常必要。

Python中則提供了強大的正則表達式處理模塊,即 re 模塊, 爲Python的內置模塊。

下面,我帶大家來一個入門demo例子,代碼如下:

import re
reg_string = "hello9527python@wangcai.@!:xiaoqiang"
reg = "hello"
result = re.findall(reg,reg_string)
print(result)

這裏reg_string就是我們的普通字符,reg就是我們的元字符。

我們使用 re 模塊中的findall函數,進行匹配,返回的結果是列表數據類型。

我們使用正則表達式,就是爲了在很長的字符串中,找到我們需要的字符串片段。

元字符

Python中常見元字符及其含義如下:

元字符 含義
. 匹配除換行符以外的任意字符
\w 匹配數字字母下劃線漢字
\s 匹配任意空白符
\d 匹配所有的數字
\b 匹配單詞的開始或結束
^ 匹配字符串的開始
$ 匹配字符串的開始結束

下面,我們具體使用下Python中的常見的元字符。

我們還是使用上次的例子,這次我們需要在reg_string匹配出我們的數字,只需要將reg換成\d,代碼如下圖所示。


比如,我們在之前的reg的hello前面加上一個^,意味着我們 匹配字符串的開始的hello,那麼結果就是一個,就是我們開頭的hello。

如果,我們把reg換成\w,代碼如下圖所示。

這樣就是匹配數字字母下劃線,包括我們的漢字。

反義代碼

Python中常見反義代碼 及其含義如下:

反義代碼 含義
\W 匹配任意不是數字字母下劃線漢字的字符
\S 匹配任意不是空白符的字符
\D 匹配非數字
\B 匹配不是單詞的開始或結束
[^a] 匹配除了a以外的任意字符
[^abcd] 匹配除了abcd以外的任意字符

其實,記憶很簡單,我們是不是知道\d匹配數字,那麼\d的大寫\D就是匹配非數字,元字符[a]匹配a任意字符,那麼[^a]就是匹配除了a以外的任意字符。

下面是具體例子

>>> import re
>>> reg_string = "hello9527python@wangcai.@!:xiaoqiang"
>>> reg = "\D"
>>> re.findall(reg,reg_string)
['h', 'e', 'l', 'l', 'o', 'p', 'y', 't', 'h', 'o', 'n', '@', 'w', 'a', 'n', 'g', 'c', 'a', 'i', '.', '@', '!', ':', 'x', 'i', 'a', 'o', 'q', 'i', 'a', 'n', 'g']
>>> reg = "[^a-p]"
['9', '5', '2', '7', 'y', 't', '@', 'w', '.', '@', '!', ':', 'x', 'q']

限定符

什麼是限定符?就是限定我們匹配的個數的東西。

Python中常見限定符 及其含義如下:

限定符 含義
* 重複零次或多次
+ 重複一次或多次
重複零次或一次
{n} 重複n次
{n,} 重複n次或更多次
{n,m} 重複n次到m次 {1,3}

我們還是用我們之前的reg_string,這次我們限定了元字符爲\d{4},也就是我們的匹配的數字必須是4個。

下面,我們來提高難度,匹配字母和數字,限定個數爲4個。

這樣我們可以使用[0-9a-z]{4},作爲我們的元字符,[0-9a-z]代表了0到9的十個數字和a到z的小寫26個英文字母。[0-9a-z]{4}限定了個數爲4個。

我們打印輸出下。

如果遇到了不是在[0-9a-z]範圍內,就會跳過,直到後面的4個都是在[0-9a-z]範圍內就打印輸出。

匹配ip地址

在互聯網中,一臺主機只有一個IP地址。IP地址用於在TCP/IP通信協議中標記每臺計算機的地址,通常用於十進制來表示,如192.168.1.100。

在window系統中,我們可以通過ipconfig查看我們的ip。在linux系統中,我們可以通過ifconfig查看我們的ip。

我們的ip字符串是這樣子的:ip = "this is ip:192.168.1.123 :172.138.2.15"

下面要求使用正則表達式,將ip匹配出來。

其實,我們主要編寫元字符。比如:reg = "\d{3}.\d+.\d+.\d+",因爲第一個數字必須是三位數開頭,我們可以設定\d{3}固定起來。


我們除了可以使用findall,還可以使用search,我們把元字符reg = "(\d{1,3}.){3}\d{1,3}"

這元字符中的\d{1,3}.指定是我們ip前三個數字,後面加{3}就是重複3次。\d{1,3}指的就是我們ip最後一個數字。

但是search和findall是有區別的,search只能匹配第一個,我們需要使用列表取出第一個,而findall匹配所有。

組匹配

什麼是組匹配,比如說這裏邊我有一個字符串s = this is phone:13888888888 and this is my postcode:012345,我需要你把手機號和驗證碼匹配出來。

因爲,我們要匹配兩個,而已每個的元字符都是不一樣的。所以,我們需要分組匹配。

正則表達式的括號表示分組匹配,括號中的模式可以用來匹配分組的內容。

於是我們的元字符就變成:reg = this is phone:(\d{11}) and this is my postcode:(\d{6})

我們一般使用search進行分組匹配,上次我是不是說過search需要使用列表取出來,這裏的組匹配也是一樣,不過這裏用的是group()方法。group(1)代表了我們的手機號,group(2)代表了我們的驗證碼,而group(0)代表了我們的手機號和驗證碼,代碼如下圖所示。

在正則表達式中,除了findall和search用法,還有一個match用法。

match用法只匹配開頭的,也是需要group()取出來,下圖match的例子。


這是的re.I是忽略大小寫的意思。

貪婪與非貪婪

貪婪與非貪婪模式影響的是被量詞修飾的子表達式的匹配行爲,貪婪模式在整個表達式匹配成功的前提下,儘可能多的匹配,而非貪婪模式在整個表達式匹配成功的前提下,儘可能少的匹配。

貪婪和非貪婪有幾個非常重要的操作符。

操作符 含義
* 重複零次或更多次
+ 重複一次或更多次
重複零次或一次

比如說這裏邊我有一個字符串reg_string = pythonnnnnnnnnpythonHelloPytho,我們先使用貪婪的模式下的元字符:reg = "python*"

貪婪模式下的reg = "python*",意味着n重複零次或更多次。所以我們看到了第一關結果的pythonnnnnnnnn儘可能多的匹配。

下面使用非貪婪的模式下的元字符:reg = "python*?",reg = "python+?",reg = "python??"


非貪婪模式下的reg = "python*",意味着n零次或一次,所以我們沒有看到pythonnnnnnnnn的結果。

手機號碼驗證

首先,我們要知道我們的手機號碼是什麼開頭的?

移動手機號碼開頭有16個號段:134、135、136、137、138、139、147、150、151、152、157、158、159、182、187、188。

聯通手機號碼開頭有7種號段:130、131、132、155、156、185、186。

電信手機號碼開頭有4個號段:133、153、180、189。

這樣我們就可以在開頭做事情了,先判斷開頭是不是上面的號段,regex = "^((13[0-9])|(14[5|7])|(15([0-3]|[5-9]))|(18[0,5-9]))\d{8}$",就是我們的元字符,代碼如下:

import re

def checkCellphone(cellphone):
    regex = "^((13[0-9])|(14[5|7])|(15([0-3]|[5-9]))|(18[0,5-9]))\d{8}$"
    result = re.findall(regex,cellphone)
    if result:
        print("匹配成功")
        return True
    else:
        print("匹配失敗")
        return False
cellphone = '13717378202'
checkCellphone(cellphone)


匹配成功
True

匹配郵箱合法性

下面,我們進行一個作業,就是來匹配我們的郵箱號碼。

作業的答案如下:


import re

def checkEmail(email):

    regex_1 = '^(\w+)@sina.com$'
    regex_2 = '^(\w+)@sina.com.cn$'
    regex_3 = '^(\w+)@163.com$'
    regex_4 = '^(\w+)@126.com$'
    regex_5 = '^[1-9][0,9]{4,}[email protected]$'
    regex = [regex_1 ,regex_2 ,regex_3, regex_4, regex_5]
    for i in  regex:
        result = re.findall(i,email)
        if result:
            print("匹配成功")
            return True
        else:
            print("匹配失敗")
            return False
email = '[email protected]'
checkEmail(email)

正則表達式測試工具

打開開源中國提供的正則表達式測試工具 http://tool.oschina.net/regex/,輸入待匹配的文本,然後選擇常用的正則表達式,就可以得出相應的匹配結果了。

例如,輸入下面這段待匹配的文本:

Hello, my phone number is 123455678 and email is [email protected], and my website is https://blog.csdn.net/weixin_44510615.

這段字符串中包含了一個電話號碼和一個電子郵件,接下來就嘗試用正則表達式提取出來,如圖所示。

在網頁右側選擇 “匹配 Email 地址”,就可以看到下方出現了文本中的 E-mail。如果選擇 “匹配網址 URL”,就可以看到下方出現了文本中的 URL。是不是非常神奇?

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章