正則表達式(regular expression)就是用一組由字母和符號組成的“表達式”來描述一個特征,然後去驗證另一個“字符串”是否符合這個特征。比如表達式“xy+” 描述的特征是“一個 ‘x’ 和 至少一個 ‘y' ”,那麼‘xy',‘xyy', ‘xyyyyyyy'都符合這個特征。

正則表達式主要應用場景

  • 驗證字符串是否符合指定特征,比如驗證用戶名或密碼是否符合要求、是否是合法的郵件地址等;
  • 用來查找字符串,從一個長的文本中查找符合指定特征的字符串,比查找固定字符串更加靈活方便;
  • 用來替換,比普通的替換更強大。

正則表達式的規則

(1)普通字符

字母、數字、漢字、下劃線、以及沒有特殊定義的標點符號,都是"普通字符"。表達式中的普通字符,在匹配一個字符串的時候,匹配與之相同的一個字符。

(2)轉義字符

  • 一些不便書寫的字符,采用在前面加“” 的方法。例如制表符、換行符等;
  • 一些有特殊用處的標點符號,在前面加“” 後,代表該符號本身。例如{,}, [, ], /, , +, *, ., $, ^, |, ? 等;

轉義字符的匹配方法與“普通字符”類似,也是匹配與之相同的一個字符。

(3)能夠與 '多種字符' 匹配的表達式

正則表達式中的一些表示方法,可以匹配 ‘多種字符’ 中的任意一個字符。例如,表達式"d" 可以匹配任意一個數字。雖然可以匹配其中任意字符,但是隻能是一個,不是多個。

(4)自定義能夠匹配 '多種字符' 的表達式

使用方括號 [ ] 包含一系列字符,能匹配其中任意一個字符。用 [^ ] 包含一系列字符,則能匹配其中字符之外的任意一個字符。雖然可以匹配其中任意一個,但是隻能是一個,不是多個。

(5)修飾匹配次數的特殊符號

(6)一些代表抽象意義的特殊符號

思考題:寫出滿足下列要求的正則表達式

  • 僅含6位數字的字符串
  • 18位身份證號碼(最後一位可能包含X)
  • 密碼(以字母開頭,長度在6~18之間,隻能包含字母、數字和下劃線)

匹配次數中的貪婪與非貪婪

在使用修飾匹配次數的特殊符號時,如“?”,“*”, “+”等,可以使同一個表達式能夠匹配不同的次數,具體匹配的次數隨被匹配的字符串而定。這種重復匹配不定次數的表達式在匹配過程中,總是盡可能多的匹配,這種匹配原則就叫作"貪婪" 模式 。例如,針對文本“dxxxdxxxd”,下列表達式匹配結果如下。

在修飾匹配次數的特殊符號後再加上一個"?" 號,則可以使匹配次數不定的表達式盡可能少的匹配,使可匹配可不匹配的表達式,盡可能的 "不匹配"。這種匹配原則叫作"非貪婪" 模式。如果少匹配就會導致整個表達式匹配失敗的時候,與貪婪模式類似,非貪婪模式會最小限度的再匹配一些,以使整個表達式匹配成功。例如,針對文本“dxxxdxxxd”,下列表達式匹配結果如下。

Python中的正則表達式庫 – re

  • re庫是Python的標準庫,不需要額外安裝,主要用於字符串匹配
  • 調用方式:import re
  • re 庫采用raw string類型表示正則表達式,rawstring是不包含對轉義符再次轉義的字符串。例如:r'[1‐9]d{5}’
  • re庫也可以采用string類型表示正則表達式,但更繁瑣,例如“'[1‐9]\d{5}'”
  • 當正則表達式包含轉義符時,建議使用raw string

re庫的主要功能函數

註意group()和groups()的區別,一個是返回匹配的字符串,一個是返回各部分匹配內容組成的元組。當表達式中沒有圓括號時,groups()返回的是空元組,當存在圓括號時,有幾個圓括號groups()返回的元組裡就有幾個元素。

正則表達式案例-驗證用戶名

編寫程序實現下述功能,提示用戶輸入用戶名,要求用戶名以字母開頭,長度不少於3位,隻能包含字母、數字、下劃線,如果用戶輸入符合要求,則提示註冊成功,否則提示用戶名不符合要求,請重新輸入,一直循環直到用戶名符合要求為止。程序執行效果如下圖所示。

參考代碼如下:

import re # 導入正則表達式庫
name = input("請輸入用戶名,以字母開頭,長度不少於3位,隻能包含字母、數字、下劃線:") # 提示用戶輸入
match = re.match(r"^[a-zA-Z]w{2,}$", name) # 驗證輸入是否符合要求
while match is None: # 如果不符合要求,則循環
print("用戶名不符合要求,請重新輸入:", end=" ") # 提示用戶名不符合要求
name = input() # 重新獲取用戶輸入
match = re.match(r"^[a-zA-Z]w{2,}$", name) # 驗證輸入是否符合要求
print("恭喜你, {} ,註冊成功!".format(name)) # 提示註冊成功