python正則表達式模塊re:正則表達式常用字符、常用可選標志位、group與groups、match、search、sub、split,findall、compile、特殊字符轉義



本文內容:

  • 正則表達式常用字符、
  • 常用可選標志位、
  • group與groups、
  • match、
  • search、
  • sub、
  • split
  • findall、
  • compile
  • 特殊字符轉義
  • 一些現實例子

 

首發時間:2018-02-07 17:17

修改:

  1. 2018-02-19 00:34:增加可選標志位re.M
  2. 2018-03-19 12:55:修改了一些文字表述,修改了一些小錯誤,增加了一些常用字符,增加了特殊字符轉義,增加了一些例子

 


re:

  • 介紹:

    關於正則表達式的模塊
  • 正則表達式字符:

字符 意義 例子【#后面代表結果】
. .代表匹配一個任意字符,\n除外 image
^ ^后面的字符串必須是待匹配字符串的開頭,否則找不到,同樣功能的是\A image

$

$前面的字符串必須是待匹配字符串的結尾,否則找不到,同樣功能的是\Z image
\d 可以匹配一個數字 image
\D 匹配一個非數字 image
\s 可以匹配一個空白字符(空格,縮進符、\n,\r),同樣功能:[\n\t\r\v\f] image
\S 匹配一個非空白字符  
\b
注:\b是字符串中的一個轉義字符,所以需要變成\\b,當然也可以使用原始字符串r"\b"
匹配的是一個單獨的單詞,有邊界,比如\bthe可以匹配出"bite the boy"的the,而不能匹配出"bithe"中的the. image
\B 與\B相反,匹配的單詞不是邊界的 image
     
可以用+、?、*來選擇匹配次數    
+ 代表匹配前一個字符一次或多次,貪婪的 image
 
? 代表匹配前一個字符0次或1次,不貪婪的 image
* 匹配*號前的字符0次或多次,貪婪的, image
+?或*?

如果問號緊跟在+或者*后面,它將直接要求+、*盡可能少的次數。

image
     
可以用 []表示范圍 注:范圍自己定,用-來代表,如可以有[0-9]、[1-9]、[1-6]、[abcd]等  
[a-z] 代表匹配范圍是a-z image
[0-9] 代表匹配范圍是0-9 image
也可以多個范圍:
[a-zA-Z0-9]
代表匹配字母或數字 image
也可以沒有-,僅僅只有字符 代表匹配[]內的字符中的一個 image

[^]

如果脫字符(^)緊跟在左方括號后面,這個符號就表示不匹配給定字符
集中的任何一個字符。

image
     
     
或:      |         用在兩個模式中間,代表匹配|左或|右的字符,如  A|B 代表可以匹配A或B image
     
可以用{m}來表示匹配次數    
{n} 代表匹配n次前一個字符 image
{n,} 代表匹配n次或更多次前一個字符 image
{n,m} 代表匹配前一個字符n到m次 image
     
可以用(...)來表示分組匹配 代表將()里面的當成一整塊來匹配,可以用於一組組數據的情況 image
可以用()來獲取子組 使用.group(組號)可以獲取之前()中匹配的結果 image
image
     
     

 

這里還有一些擴展表示法沒寫出來。

更多:https://baike.baidu.com/item/%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F/1700215?fr=aladdin

 


常用可選標志位:

  • re.S:  
    • 使 . 匹配包括換行在內的所有字符

image

 

  • re.I:      
    • 匹配忽略大小寫

image

 

  • re.M:
    • 進行多行匹配,在新的一行中,同樣可以使用^來匹配該行字符串的開頭,用$來匹配該行字符串的結尾

【英文文檔原意:

M  MULTILINE   "^" matches the beginning of lines (after a newline)
as well as the string.
"$" matches the end of lines (before a newline) as well
as the end of the string.

image

 

  • 如果想同時使用多個標志位,需要使用|:

image


group與groups:

match和search匹配的返回結果都是對象,如果要獲取對應字符串,需要使用group(num) 或 groups() :

image

group(num=0):

直接調用則返回整個匹配結果,

如果group里面有參數:group(0)代表整個匹配結果,group(1) 列出第一個分組匹配部分,group(2) 列出第二個分組匹配部分,group(3) 列出第三個分組匹配部分,以此類推。

image

groups()

以元組返回所有分組匹配的字符

image
 

附加:

  •  start([group]) 方法用於獲取分組匹配的子串在整個字符串中的起始位置(子串第一個字符的索引),參數默認值為 0;
  • end([group]) 方法用於獲取分組匹配的子串在整個字符串中的結束位置(子串最后一個字符的索引+1),參數默認值為 0;
  • span([group]) 方法返回 (start(group), end(group))image
  • 沒有子組的情況下是返回整個匹配結果的start和end:image
  • 只有有group方法的查找方式的結果才有start,end,span,而findall是沒有的
 

re.match(pattern, string, flags=0):

功能:

re.match 從頭開始匹配,如果字符串開頭不匹配,那么返回None【如果匹配模式是】

參數介紹:

  • pattern:匹配的正則表達式
  • string:要匹配的字符串。
  • flags:標志位,用於控制正則表達式的匹配方式,如:是否區分大小寫,多行匹配等等。

image


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

功能:

re.search 搜索整個字符串,返回第一個匹配結果

參數介紹:

  • pattern:匹配的正則表達式
  • string:要匹配的字符串。
  • flags:標志位,用於控制正則表達式的匹配方式

image

 


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

功能:

re.sub      用於替換字符串中的匹配項,可指定替換個數

參數介紹:

  • pattern : 正則中的模式字符串。
  • repl : 替換的字符串,也可為一個函數。
  • string : 要被查找替換的原始字符串。
  • count : 模式匹配后替換的最大次數,默認 0 表示替換所有的匹配。
  • flags:標志位,用於控制正則表達式的匹配方式

用法:

import re

print(re.sub("abc","ABC","123abc123"))#123ABC123
print(re.sub("abc","ABC","123abc123abc123abc",2))#123ABC123ABC123abc
print(re.sub("abc","ABC","123abc123abc123abc",2))#123ABC123ABC123abc

def func(x):
    x=int(x.group())+1
    return str(x)

print(re.sub("123",lambda x:str(int(x.group())+1),"123abc123"))#124abc124
print(re.sub("123",func,"123abc123"))#124abc124

 

補充:

  • subn()與sub()的區別:
    • subn()和 sub()的功能一樣,但 subn()還返回一個表示替換的總數,替換后的字符串和表示替換總數的數字一起作為一個擁有兩個元素的元組返回。

 

re.split(pattern, string, maxsplit=0, flags=0):

功能:

基於正則表達式的模式分隔字符串

參數介紹:

  • pattern : 正則中的模式字符串。
  • string : 要被分割的原始字符串。
  • maxsplit:分割的最大次數

用法:

import re
rel=re.split(':', 'str1:str2:str3')
print(rel)#['str1', 'str2', 'str3']

 


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

功能:

re.findall 搜索整個字符串,把所有匹配到的字符串以列表中的元素返回

參數介紹:

  • pattern : 正則中的模式字符串。
  • string : 待匹配的字符串。
  • flags:標志位,用於控制正則表達式的匹配方式

 

用法:

image

 

補充:

  • 對於使用了分組的正則表達式,findall只會返回各個分組的內容:

image

  • finditer()函數與findall()函數不同的是返回的是一個迭代器

 


re.compile 函數

功能:

  • compile 函數用於編譯正則表達式,生成一個正則表達式( Pattern )對象

image

 

補充:

為什么需要compile()【摘自Python核心編程】:

  • eval()或者 exec(在 2.x 版本中或者在 3.x 版本的 exec()中)調用一個代碼對象而不是一個字符串,性能上會有明顯提升
  • 使用預編譯的代碼對象比直接使用字符串要快,因為解釋器在執行字符串形式的代碼前都必須把字符串編譯成代碼對象。
  • 同樣的概念也適用於正則表達式 — 在模式匹配發生之前,正則表達式模式必須編譯成正則表達式對象。由於正則表達式在執行過程中將進行多次比較操作,因此強烈建議使用預編譯。而且,既然正則表達式的編譯是必需的,那么使用預編譯來提升執行性能無疑是明智之舉。re.compile()能夠提供此功能。

 

complie()與purge():

其實模塊函數會對已編譯的對象進行緩存,所以不是所有使用相同正則表達式模式的 search()和 match()都需要編譯。即使這樣,你也節省了緩存查詢時間,並且不必對於相同的字符串反復進行函數調用。在不同的 Python 版本中,緩存中已編譯過的正則表達式對象的數目可能不同,而且沒有文檔記錄。purge()函數能夠用於清除這些緩存。

 

 


上面的演示的代碼:

import re

print(".".center(50,'-'))
print(re.match(".","abc"))#<_sre.SRE_Match object; span=(0, 1), match='a'>
print(re.match(".","abc").group())# a
print(re.match(".","abc").groups())# a

print("+".center(50,'-'))
print(re.match("a+","aaaa").group())#aaaa

print("?".center(50,'-'))
print(re.match("a?","aaaa").group())#a

print("*".center(50,'-'))
print(re.match("a*","aaaa").group())#aaaa


print("^".center(50,'-'))
print(re.search("^a.b","acbd").group())#acb
print(re.match("^a.+","abc").group())
print(re.search("^a.b","123acbd"))#這樣找不到

print(re.search("a.+d$","acbd").group())#acbd
print(re.search("a.+d$","acbdc"))#這樣找不到
print("".center(50,'-'))


print("\d".center(50,'-'))
print(re.match("\d","123456").group())#1
print(re.match("\d+","123456").group())#123456

print("\D".center(50,'-'))
print(re.search("\D","123456b").group())#b
print(re.search("\D","a123456").group())#a

print("\s".center(50,'-'))
print(re.search("a\sb","123a b456").group())#a b


print("[]".center(50,'-'))
print(re.search("[a-z]+","abcdefg").group())#abcdefg
print(re.search("[a-k]+","abczefg").group())#abc

print(re.search("[0-9]+","123456").group())#123456
print(re.search("[0-4]+","123456").group())#1234

print(re.search("[a-zA-Z0-9]+","1a2bC456ef").group())#1a2bC456ef

print("".center(50,'-'))
print(re.search("[a-z]+|[A-Z]+","1ab2bC4ef").group())#ab
print(re.search("([a-z]|[A-Z])+","1ab2bC4ef").group())#ab


print("{n}{n,m}".center(50,'-'))
print(re.search("[a-z]{3}","1ab2bC4efg").group())#efg
print(re.search("[a-z]{2,3}","1ab2bC4efg").group())#ab
print(re.search("[a-z]{2,3}","1a2C4efg").group())#efg
print(re.search("[a-z]{2,}","1a2C4efgaaaa").group())#efgaaaa


print("分組匹配".center(50,'-'))

print(re.search("([a-z]|[A-Z])+","1ab2bC4ef").group())#ab
print(re.search("([a-z]|[A-Z])+","1ab2bC4ef").group())#ab


print("group groups".center(50,'-'))
print(re.search("(\d[a-z]\d){3}","1x11a32a465").group())#1x11a32a4
print(re.search("(abc){3}","abcabcabc123").group())#abcabcabc
print(re.search("(abc)","abcabcabc123").groups())#('abc',)
m=re.search("(abc)(cba)(def)","abccbadef123")
print(m.groups())#('abc', 'cba', 'def')
print(m.group(0))#abccbadef
print(m.group(1))#abc
print(m.group(2))#cba

print("findall".center(50,'-'))
print(re.findall("(abc)","abcabcabc123"))#['abc', 'abc', 'abc']



print("flag".center(50,'-'))

print(re.search("a.b","a\nb",re.S).group())#分兩行打印的 a b

print(re.search("a.b","A\nb",re.S|re.I).group())#分兩行打印的 A b

print(re.search("ab","Ab",re.I).group())#Ab

 

 


特殊字符轉義:

 

2018-03-18:前幾天遇到一個人問我一個正則問題,才發現忘記寫下特殊字符轉義的情況了。

 

特殊字符轉義:遇到正則表達式定義好的字符該怎么匹配出來這樣的問題時利用轉義來標注特定字符使用非正則功能的字符意義

 

比如:

想要匹配一個.,可以使用"\."或"\\."

想要匹配一個"[" 或 "]",可以使用

 

 

import  re

rel=re.search(".","a.a")
print(rel.group())
rel=re.search("\\.","a.a")
print(rel.group())
rel=re.search("\.","a.a")
print(rel.group())

rel=re.search("\[","-[用戶名]-")
print(rel.group())
rel=re.search("\[\]","-[]-")
print(rel.group())
rel=re.search("\\[","-[用戶名]-")
print(rel.group())
rel=re.search("\[(\w+)\]","-[用戶名]-")
print(rel.group())

 


一些現實例子:

 

整數:^(0|[1-9][0-9]*)$

正浮點數:^\d+(\.\d+)?$

Email地址:^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$

手機號碼:^(13[0-9]|14[5|7]|15[0|1|2|3|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])\d{8}$

電話號碼(“XXX-XXXXXXX”、”XXXX-XXXXXXXX”、”XXX-XXXXXXX”、”XXX-XXXXXXXX”、”XXXXXXX”和”XXXXXXXX):^($$\d{3,4}-)|\d{3.4}-)?\d{7,8}$

身份證號(15位、18位數字):^\d{15}|\d{18}$

IP地址:\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}image_thumb[1]

 

 

 



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM