1. 程式人生 > 實用技巧 >Python之re正則

Python之re正則

1. 基本規則

# 元字元:  
    # . ^ $ * + ? { } [ ] | ( ) \

# 字元型別匹配:
    #  .  表示匹配任意一個字元(換行符除外)
    #  [asdf]  表示匹配中括號裡面的任意一個字母一次 
    #  [a-z]  表示匹配a-z中的任意一個字母    [0-9] 表示匹配0-9中的任意一個數字
    #  [^0-9] 中括號中有^符號,表示非,除---之外,這裡表示除0-9之外的任意字元

    # \d 匹配數字,即 [0-9]
    # \D 匹配⾮數字,即不是數字 [^0-9]
    # \s 匹配空⽩,即 空格,tab鍵 [\t\n\r\f\v]
# \S 匹配⾮空⽩ [^\t\n\r\f\v] # \w 匹配單詞字元,即a-z、A-Z、0-9、_ [a-zA-Z0-9_] # \W 匹配⾮單詞字元 [^[a-zA-Z0-9_]] # \b 匹配一個特殊字元邊界,比如 空格、&、# 等 # 定位: # ^ 表示起始定位 # $ 表示結束定位 # 匹配次數: # * 表示任意次 # + 至少1次 [1,+oo] # ? 匹配0次或者1次 # {a,b} 匹配指定的次數範圍,如 {0,}相當於匹配任意次 ,{6} 表示匹配6次 #
分組 & 後向引用 & 別名: # (ab) 將括號中字元作為⼀個分組 # \num 引⽤分組num匹配到的字串 # (?P<name>) 分組起別名 # (?P=name) 引⽤別名為name分組匹配到的字元 # | 匹配左右任意⼀個表示式

2. findall

2.1 貪婪匹配&惰性匹配

1)貪婪模式

  • findall預設就是貪婪模式,其會盡可能多的匹配
  • findall會將所有匹配符合的內容儲存到一個列表中
import re   # 匯入re模組

# findall方法第一個引數是匹配的規則,第二個引數是要匹配的字串
# findall會將所有匹配符合的內容儲存到一個列表中 print(re.findall("hgzero", "thisishgzero"))   # 輸出:[hgzero]
data1 = re.findall("hg", "hgzerohgwzh") print(data1)   # 輸出:['hg', 'hg']

2)惰性模式

  • 惰性模式就是儘可能少的去匹配
data1 = re.findall("hg*", "hggggg")  # 貪婪模式
data2 = re.findall("hg*?", "hggggg") # 惰性模式,後面的那個問號就表示惰性模式
print(data1)  # 輸出:['hggggg']
print(data2)  # 輸出:['h']

2.2 字串轉義流程

字串轉義的流程:字串 --> python直譯器轉義 --> re模組的轉義

# 轉義
ret1 = re.findall("www.baidu", "www.baidu")   # 這裡面的 . 會代指任意字元(除\n外)
ret1 = re.findall("www\.baidu", "www.baidu")  # 這裡面,反斜槓的新增會讓 . 符號失去元字元代指的意義,從而使其就表示普通的點 . 符號

# 字串轉義的流程:  字串---> python直譯器轉義---> re模組的轉義 
ret2 = re.findall(r"I\b", "I hIo Ion")    # 這裡面的r ,表示在python層次不使用轉義字元,直接將其傳遞給re模組
ret3 = re.findall("I\\\\b", "I hIo Ion")  # 這裡適用4個\ , 表示在python直譯器層次轉義成2個\ , 然後再將其傳入re模組進行轉義


re.findall("I\\b", "I what")   # 這樣使\\b在python層次被轉義成\b傳遞給re模組
re.findall(r"I\b", "I what")   # 這樣在前面加上r ,可以讓python不轉義字串內容,而直接傳遞給re

3. search

search會將匹配到的結果儲存到一個物件中,且只匹配第一個物件。

用search取到的物件必須要用group取值。

# search會將匹配到的結果儲存到一個物件中,且只匹配第一個物件
sear = re.search("\d+", "fasdfsaf345kdf89")  # search返回的只是一個物件,且只返回找到的第一個
retu = sear.group()   # 用search取到的物件必須要用group取值

# 可以用?P<name>的形式給某一部分命名別名
re.search("(?P<name>[a-z]+)(?P<age>\d+)", "hgzero21wzh23hg26").group("name")
re.search("(?P<name>[a-z]+)(?P<age>\d+)", "hgzero21wzh23hg26").group("age")

4. match

match只從開始開始匹配,且只匹配一次,返回一個物件,若沒匹配到則什麼都不返回

# match只從開始開始匹配,且只匹配一次,返回一個物件,若沒匹配到則什麼都不返回
re.match("\d+", "234fda") 

5. split

split會將字串按照某字元分割,然後儲存為一個列表

# split會將字串按照某字元分割
re.split(" ", "hello abc what")    # 將字串按照空格分割,儲存到一個列表中
re.split("[ |]", "hello welcome|hi hgzero") # 將字串按照空格或者|進行分割後儲存到一個列表中

re.split("[ab]", "abc")  # 先按照a分割,左邊形成一個空,然後將得到的bc再按照b分割,左邊又得到一個空
# 列印結果為  ['', '', 'c']

6. sub

sub可以完成字串的替換功能

# sub可以完成字串的替換功能
re.sub("\d+", "A", "welcome666hgzero987")   # 將第三個引數中的字串中的數字轉換成A
# 這裡面的第四個引數可以限定匹配替換的次數

re.subn("\d", "A", "welcome666hgzero987")  
# 將匹配到的內容放在一個元組裡,結果中的第二個值為匹配替換的次數 # 列印結果為 ('welcomeAAAhgzeroAAA', 6)

7. compile

compile可以事先定義好規則,儲存為一個物件,然後後面可以直接使用這個物件而無需再定義規則

# compile可以事先定義好規則,儲存一個物件,然後後面可以直接使用這個物件而無需再定義規則
com = re.compile("\d+")
com.findall("welcome666hgzero987")

8. finditer

finditer可以將得到的資料儲存到一個迭代器中

# finditer可以將得到的資料儲存到一個迭代器中
ret = re.finditer("\d", "welcome666hgzero987")
next(ret).group()    # 可以通過next函式加上group呼叫迭代器中的內容


re.findall("www\.(baidu|163)\.com", "www.baidu.com")  # findall會優先將分組中的內容返回
# 這裡的返回結果為  ['baidu']
re.findall("www\.(?:baidu|163)\.com", "www.baidu.com")  #  【在分組中加上 ?: 可以去掉分組的優先順序】