1. 程式人生 > >Python中正則表達式(re模塊)的使用

Python中正則表達式(re模塊)的使用

python中正則表達式

Python中正則表達式(re模塊)的使用

1、正則表達式的概述

(1)概述:正則表達式是一些由字符和特殊符號組成的字符串,他們描述了模式的重復或者表示多個字符,正則表達式能按照某種模式匹配一系列有相似特征的字符串。正則表達式是一種小型的、高度的專業化的編程語言,

(2)Python語言中的正則表達式內嵌在Python中通過re模塊實現,正則表達式被編譯成一系列的字節碼,然後由C編寫的匹配引擎執行

2、字符匹配

(1)符號匹配

符號

描述

示例

實例說明

literal

匹配文本字符串的字面值literal

root

匹配字符串root

re1|re2

匹配正則表達式re1或者re2

root|admin

匹配字符串root或者admin

.

匹配除換行外的任意字符

a.c

匹配ac中間有任意一個字符的選項

^

匹配字符串的起始部分

^root

匹配以root開頭的結果

$

匹配字符串的結束部分

*sh$

匹配以sh結尾的內容

*

匹配0次或多次前面出現的內容的正則表達式

[a-z]*

匹配0次或多次出現小寫字母

+

匹配1次或多次前面出現的內容的正則表達式

[A-Z]+

匹配大寫字母至少出現一次

匹配0次或1次前面出現的正則表達式

goo?

匹配go或者goo

[…]

匹配來自字符集的任一單一字符

a[0-9]c

匹配ac中間出現一個數字

[..x-y..]

匹配x到y範圍中的任一單一字符

[a-zA-Z]

匹配字母

[^…]

不匹配此字符集中出現的任何一個字符,包括某一範圍字符

[^A-Za-z0-9]

匹配非字母、數字

{n}

匹配n次前面出現的正則表達式

[0-9]{3}

匹配三個數字

{n,m}

匹配n到m此前面出現的正則表表達式

[0-9]{5,7}

匹配數字出現5到7次

(…)

匹配封閉的正則表達式,然後另存為子組

([0-9]{3}\.)

匹配三個數字+.存為一個組

(2)特殊字符的匹配

符號

描述

示例

\d

匹配任何十進制數字,與[0-9]一致

data\d+.txt

\D

匹配任何非數字

a\D?\.log

\w

匹配任何字母數字字符(\W與之相反)

[A-Za-z]\w+

\s

匹配任何空格字符,與[\n\t\r\v\f]相同,\S功能相反

of\sthe

\b

匹配任何單詞邊界(\B功能相反)

\bthe\b

\N

匹配以保存的子組N

price

:\16

\A(\Z)

匹配字符串的起始(結束)

\ADear

3、python正則表達式的使用(即re模塊的使用)

函數/方法

作用

compile(pattern,flags=0)

使用任何可選的標記來編譯正則表達式的模式,然後返回一個正則表達式對象

re模塊函數和正則表達式對象的方法

match(pattern,string,flags=0)

嘗試使用帶有可選的標記的正則表達式的模式來匹配字符串,如果匹配成功就返回匹配對象;失敗,返回none

search(pattern,string,flags=0)

使用可選標記搜索字符串中第一次出現正則表達式的模式,如果匹配成功則返回匹配對象,失敗,返回none

findall(pattern,string[,flags])

查找字符串中所有(非重復)出現的正則表達式模式,如果匹配成功,則返回匹配對象,如果失敗,返回none

finditer(patter,string[,flags])

與findall函數相同,但返回的不是一個列表,而是一個叠代器,對於每一次匹配,叠代器都返回一個匹配對象

split(pattern,string,max=0)

根據正則表達式的模式分隔符,split函數將字符串分割為列表,然後返回成功匹配的列表,分割最多操作max次(默認分割所有)

sub(pattern,repl,string,count=0)

使用repl替換所有正則表達式的模式在字符串中出現的位置,除非定義count,否則,就替換所有出現的位置

purge()

清楚隱式編譯的正則表達式

group(num=0)

返回整個匹配對象,或者編號為num的特定子組

groups(default=None)

返回一個包括所有子組的元組,(如果沒有匹配成功,則返回一個空元組)

groupdict(default=None)

返回一個包含所有匹配的的命名子組的字典,所有的子組名稱作為字典的鍵(如果沒有匹配,則返回空字典)

(1)compile()函數

1)re.compile(strPattern[,flag])方法概述:

這個方法是Pattern類的工廠方法,用於將字符串形式的正則表達式編譯為Pattern對象。第二個參數flag是匹配模式取值可以使用按位或運算符,‘|’表示同時生效,比如re.I|re.M

2)作用:可以把經常使用的正則表達式編譯成正則表達式對象,這樣可以提高一定的效率。如:

import  re
 text = "Jgood  is a handsome boy,he is cool,clever, and so on..."
 regex =  re.compile(r‘\w*oo\w*‘)    #將正則表達式編譯成對象
 print(regex.findall(text))

(2)通過match()方法匹配字符串

1)作用:從起始位置(開頭)開始匹配,匹配成功返回一個對象,未匹配成功返回None

2)語法:match(pattern, string, flags=0)

pattern: 正則模型

string: 要匹配的字符串

falgs : 匹配模式

3)matchobect對象的方法

group():返回被RE匹配的的字符串

start():返回匹配開始的位置

end():返回匹配結束的位置

span():返回一個元組包含匹配(開始,結束)的位置

group():返回re整體匹配的字符串,可以一次輸入多個組號,對應組號匹配的字符串

group(n,m) :返回組號為n,m所匹配的字符串,如果組號不存在,則返回組號匹配的字符串

groups():返回一個包括正則表達式中所有小組字符串的元組,從1到所含的小組號,通常 groups()不需要參數,返回一個元組,元組中元素是正 則表達式中定義的組

import re
origin = "has dfuojqwlm098"
# r = re.match("h\w+", origin)
# r = re.match("h(\w+)", origin)  #在匹配到的數據中再通過\w+去匹配
r = re.match("h(?P<name>\w+)", origin)   #給分組名名
print(r.group())  # 獲取匹配到的所有結果
print(r.groups())  # 獲取模型中匹配到的分組結果
print(r.groupdict())  # 獲取模型中匹配到的分組結果

(3)使用search()在一個字符串中查找匹配

1)作用:search()會用它的字符串參數,在任意位置對給定正則表達式模式搜索第一次出現的匹配情況。如果搜索到成功的匹配,就會返回一個匹配對象;否則,返回None.

2)用法:同match()

importre
m =re.match(‘foo‘,‘seafood‘)
if m isnot None:
    print(m.group())    #使用match匹配不到,所以沒有打印
 
m =re.search(‘foo‘,‘seafood‘)
if m isnot None: 
    print(m.group())     #使用search匹配到了foo

origin = "has dayi haha hal dfuojdayi098"

r = re.search("d(\w+).*(?P<name>\d)$", origin)
print(r.group())  # 獲取匹配到的所有結果
print(r.groups())  # 獲取模型中匹配到的分組結果
print(r.groupdict())  # 獲取模型中匹配到的分組中所有執行了key的組

(4)重復、特殊字符及分組匹配

正則表達式中最常見的情況包括特殊字符的使用,正則表達式模式的重復出現,以及使用圓括號對匹配模式的各部分進行分組和提取操作。

import re
#一個分組多次匹配
# patt = ‘\w+@(\w+\.)?\w+\.com‘     #創建一個匹配規則,要求括號中的內容出現0次或一次
# print(re.match(patt, [email protected] is mail‘).group())

patt = ‘\w+@(\w+\.)*\w+\.com‘     #創建一個匹配規則,匹配括號中的內容出現0次或多次
print(re.match(patt,[email protected] is mail‘).group())

#多個分組分別匹配
m = re.match(‘(\w\w\w)-(\d\d\d)‘, ‘abc-123‘)
print(m.group(1))   #打印分組以中的內容
print(m.group(2))  #打印分組2中的內容
print(m.group())  #打印分組中的所有內容

#分組嵌套匹配
n = re.match(‘(a(b))‘, ‘abcdefgh‘)
print(n.group(1))   #打印匹配到的分組1,即‘(a(b))‘
print(n.group(2))   #打印匹配到的分組2即‘(b)‘
print(n.groups())  #打印匹配到的所有分組,即‘(ab)‘,‘(b)‘

(5)匹配字符串的起始結尾及單詞邊界

import re

#開頭匹配
print(re.search(‘^dayi123‘, ‘dayi123 is nb‘).group())
# print(re.search(‘^dayi‘, ‘her is dayi‘).group())

#邊界匹配
print(re.search(r‘\bhello‘, ‘hello world‘).group())#print(re.search(r‘\Bhello‘,‘worldhellower‘).group()) #有邊界匹配時會報錯
print(re.search(r‘\Bhello‘, ‘worldhellower‘).group())

(6)使用findall和finditer()查找每一次出現的位置

findall()查詢字符串中某個正則表達式模式全部的非重復出現的情況,findall返回的是一個列表,如果沒有匹配到則返回一個空列表,如果匹配成功,列表包含所有成功的匹配部分(從左向有按順序排列)

import re
origin = "has haha hal dfuojqwlm098"

print(re.findall("h\w+", origin))   #找到字符串中所有的匹配到的內容
print(re.findall("h(\w+)", origin))   #打印匹配到的列表
r = re.findall("h(\w+)a(bc)c", origin) #因為匹配不到所有打印一個空列表
print(r)

finditer()函數與findall函數類似,但finditer()返回的是一個可叠代的對象。

import re
s = ‘This and that‘
print(re.findall(r‘(Th\w+) and (th\w+)‘, s, re.I))
print(re.finditer(r‘(Th\w+) and (th\w+)‘, s, re.I).__next__().groups()) #調用返回值
print(re.finditer(r‘(Th\w+) and (th\w+)‘, s, re.I).__next__().group(1))
it = re.finditer(r‘(Th\w+)‘, s, re.I)   #生成一個生成器對象
g = it.__next__()   #調用
print(g.groups())   #打印出This,以元組的形式
print(g.group(1))
g = it.__next__()  #再次調用
print(g.groups())  #打印出that
#將匹配到的內容生產一個列表,列表中包含兩個元組
print([g.groups(1) for g in re.finditer(r‘(Th\w+)‘, s, re.I)])

(7)使用sub()和subn()搜索替換

sub()只替換搜索到的內容,subn()不但替換搜索到的內容,並返回替換的次數。

import re
print(re.sub("g.t","have",‘I get A, I got B,I gut C‘))  #對匹配到的單詞替換
print(re.subn("g.t","have",‘I get A, I got B,I gut C‘)) #對匹配到的單詞替換,並返回替換次數
print(re.sub(‘[bd]‘,‘Y‘,‘abcdef‘))
print(re.subn(‘[bd]‘,‘Y‘,‘abcdef‘))    #對字符串替換,並打印替換的字符串的的次數

分組和替換的綜合應用(替換日期的表示方法):

import re
import time,datetime
day1 = str(datetime.date.today())
print(day1)
#將月/日/年的時間格式轉化成“日/月/年”,將r加在左引號之前,主要目的是為了避免轉義特殊字符串字符
print(re.sub(r‘(\d{1,2})/(\d{1,2})/(\d{2}|\d{4})‘, r‘\2/\1/\3‘, ‘05/06/2017‘))
print(re.sub(r"(\d{2}|\d{4})-(\d{1,2})-(\d{1,2})", r"\3/\2/\1", day1))

(8)使用split分割字符串

import re
print(re.split(‘\d+‘,‘one1two2three3,for4‘)) #以匹配到的數字對字符串以“,”進行分割

4、正則表達式的應用

(1)對Linux系統who命令輸出內容進行處理

將Linux系統who命令輸出結果保存到whodata.txt中:

[[email protected] ~]# cat whodata.txt

liu2 :0 2017-04-17 22:10 (:0)

liu2 pts/0 2017-04-17 22:11 (:0)

root pts/1 2017-05-05 03:51(172.16.252.112)

root pts/2 2017-05-05 03:51(172.16.252.112)

root pts/3 2017-05-05 03:52 (172.16.252.112)

對who命令輸出的內容進行處理:

import re
f = open(‘whodata.txt‘,‘r‘)
for line in f:    
    #對匹配到的行的內容以逗號分隔,將每一行的內容分別存到一個列表中
    print(re.split(r‘\s\s+‘,line.rstrip())) 
f.close()

使用findall()函數處理win下tasklist命令:

import os
import re
f = os.popen(‘tasklist /nh‘, ‘r‘)
for line in f:
    print(re.findall(r‘([\w.]+(?:[\w]+)*)\s\s+(\d+) \w+\s\s+\d+\s\s+([\d,]+ K)‘, line.rstrip())) 
    #讀取每一行中自己需要的數據

f.close()

(2)生成用於正則表達式練習的數據

#!/usr/bin/env python
from random import randrange,choice
from stringimport ascii_letters as lc
from sys import maxsize
from time import ctime

tlds = (‘com‘,‘deu‘,‘net‘,‘org‘,‘gov‘)
for i in range(randrange(5,11)):
    dtint = randrange(maxsize)        #生成一個隨機數字組
    #在屬組中取一個6到十位的隨機數作為時間戳生成一個日期
    dtstr = ctime(int(str(dtint)[0:randrange(6,10)])) 
    llen = randrange(4,8)   #生成一個4-8的隨機數字
    login = ‘‘.join(choice(lc) for j in range(llen)) [email protected]
    dlen = randrange(llen,13)
    dom = ‘‘.join(choice(lc) for j in range(dlen))  [email protected],長度有dlen來決定
    #choice(tlds)為在tlds總隨機選擇一個域名後綴
    print(‘%s::%s@%s.%s::%d-%d-%d‘ % (dtstr,login,dom,choice(tlds),dtint,llen,dlen))

將上面生成的數據保存到一個文件中用於後面練習:

#!/usr/bin/env python
import re
with open(‘gendata.txt‘,‘r‘) as f:
    for line in f:
        patt = ‘.+(\d+-\d+-\d+)‘ #為貪婪匹配,匹配前面為任意字符,後面組中為如“5-7-10”的數據
        print(re.match(patt, line).group(1))        
        ‘‘‘"?"要求正則表達式引擎匹配盡可能少的字符,在"+","*","?"後使用可達到預期效果‘‘‘
        patt1= ‘.+?(\d+-\d+-\d+)‘ #通過"?",匹配到了符合分組中的所有字符串
        print(re.match(patt1, line).group(1))


本文出自 “dayi123” 博客,請務必保留此出處http://dayi123.blog.51cto.com/12064061/1922559

Python中正則表達式(re模塊)的使用