1. 程式人生 > >Python常用模組——re模組

Python常用模組——re模組

  有些人在面臨問題的時候會想:“我知道,我將使用正則表示式來解決這個問題。”這讓他們面臨的問題變成了兩個。

                                    —— Jamie Zawinski

首先我們對比一下兩段程式碼處理使用者輸入手機號的不同

1 phone_num = input('請輸入手機號:')
2 if len(phone_num) == 11 \
3         and phone_num.isdigit()\
4         and phone_num[:3] in ['130','131','132']:
5     print
('hello') 6 else:print('非聯通號!')
程式碼1
1 import re
2 phone_num = input('請輸入手機號:')
3 if re.findall('^(130|131|132)[0-9]{8}$',phone_num):
4     print('hello')
5 else:print('非聯通號!')
程式碼2

對比來看程式碼1比較通俗易懂,程式碼2看起來有些不太容易理解但是可以使得程式碼更加的簡潔

 1.正則表示式

re模組提供了對正則表示式的支援,學習re模組之前要了解正則表示式:

正則表示式其實是匹配文字片段的模式,最簡單的正則表示式是普通的字串,與自己匹配,可以使用這種匹配行為來完成一下工作:在文字中查詢模式,將特定的模式替換為計算得到的值,以及將文字分割為片段。

正則表示式線上測試工具  http://tool.chinaz.com/regex/

1.1萬用字元

. 匹配除換行符以外的任意字元
\w 匹配字母或數字或下劃線
\s 匹配任意的空白符
\d 匹配數字
\n 匹配一個換行符
\t 匹配一個製表符
\b 匹配一個單詞的結尾
^ 匹配字串的開始
$ 匹配字串的結束
\W 匹配非字母或數字或下劃線
\D 匹配非數字
\S 匹配非空白符
a|b 匹配字元a或字元b
() 匹配括號內的表示式,也表示一個組
[...] 匹配字符集中的字元
[^...] 匹配除了字符集中的字元

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 1.2字符集

用方括號將一個子串括起來,建立一個所謂的字符集

例如"[a-zA-Z0-9]"與大小寫字母以及數字都匹配,但需要注意的是字符集只能匹配一個字元

要排除字元就可以在開頭加上^字元,例如"[^abc]"與除a、b和c外的其他任何字元都匹配

字符集 匹配字元 結果 說明
[0123456789] 1 True
在一個字元組裡列舉合法的所有字元,字元組裡的任意一個字元
和"待匹配字元"相同都視為可以匹配
[0-9] 1 True
也可以用-表示範圍,[0-9]就和[0123456789]是一個意思
[a-z] a True
   同樣的如果要匹配所有的小寫字母,直接用[a-z]就可以表示
[A-Z] A True [A-Z]就表示所有的大寫字母

 

 

 

  

 

 

 

 

1.3量詞

* 重複零次或更多次
+ 重複一次或更多次
? 重複零次或一次
{n} 重複n次
{n,} 重複n次或更多次
{n,m} 重複n到m次

 

 

 

 

 

 

1.4分組 ()與 或 |[^]

匹配身份證號為15或18位字串組成,15位為純數字,首位不能為零。

                       正則            待匹配字元 匹配結果 說明
^[1-9]\d{13,16}[0-9x]$ 53010219200508011x 53010219200508011x 雖可匹配但存在問題
^[1-9]\d{14}(\d{2}[0-9x]$)? 53010219200508011x 53010219200508011x 括號內為子模式,子模式後加量詞
([1-9]\d{16}[0-9x]|[1-9]\d{14}) 53010219200508011x 53010219200508011x 括號內加"|",變為二選一模式,先匹配前面後匹配後面

 

 

 

 

1.5 特殊字元進行轉義

普通字元與自己匹配,但特殊字元情況不同,要讓特殊字元與普通字元一樣就要對其進行轉義:在正則前加"\"

請注意,為表示模式re要求的單個反斜槓,需要在字串中寫兩個反斜槓,讓直譯器對其轉義,包含兩層含義,直譯器執行的轉義和模組re進行的轉義

當然可以使用原始字串,如r'\d'

>>> import re

>>> print(re.findall('\\\\d', '\\d'))  # 匹配字元"\d"時,正則表達為"\\d",然後Python還要對其中兩個斜槓在進行轉義,最終規則表示式為"\\\\d"
['\\d']

>>> print(re.findall(r'\\d',r'\d')) # 使用原始字串省去不必要的麻煩
['\\d']

1.6 貪婪和非貪婪匹配 

 貪婪匹配:在滿足匹配時,匹配儘可能長的字串,預設情況下,採用貪婪匹配

加上"?"變為非貪婪匹配

*? 重複任意次,但儘可能少重複
+? 重複1次或更多次,但儘可能少重複
?? 重複0次或1次,但儘可能少重複
{n,m}? 重複n到m次,但儘可能少重複
{n,}? 重複n次以上,但儘可能少重複

一般這樣使用時要加上結尾條件,否則只會匹配量詞的最少重複次數
你.*? 你好嗎
你.*?嗎 你好嗎你真的好嗎

你好嗎
你真的好嗎

 

 

 

2.模組re的常用函式

函式 描述
compile(pattern, flags=0) 根據包含正則表示式的字串建立模式物件
escape(string) 對字串中的所有正則表示式的特殊字元進行轉義
findall(pattern, string, flags=0) 返回一個列表,其中包含字串中的所有與正則模式匹配的子串
search(pattern, string, flags=0) 在字串中查詢模式
split(pattern, string, maxsplit=0, flags=0) 根據模式來分割字串
sub(pattern, repl, string, count=0, flags=0) 將字串中與模式匹配的子串替換為 repl
match(pattern, string, flags=0) 在字串開頭查詢模式
subn(pattern, repl, string, count=0, flags=0) 將字串中與模式匹配的子串替換為 repl,返回元組,元組包含替換後結果和替換次數
finditer(pattern, string, flags=0) 返回一個包含結果的迭代器

 

 

 

 

 

 

 

 

 

 

print(re.findall('','你好你是')) # ['你', '你']

ret = re.search('','好是') # 找到後需要呼叫group()方法,找不到返回None,None不能呼叫group()方法
if ret:
    print(ret.group())

ret = re.match('','ni好你是') # 和search用法類似
if ret:
    print(ret.group())

ret = re.split('b','abc') # 按“b”分割字串
print(ret) # ['a', 'c']

ret = re.split('[ad]','adbcde') # 先按“a”分割,再按“b”分割
print(ret) 

print(re.sub('\d','$','zhao123'))
print(re.subn('\d','$','zhao123'))

obj = re.compile('你好')
ret = obj.findall('你好嗎')
print(ret)

ret = re.finditer('你好','你好嗎你好')
print(ret.__next__().group())