1. 程式人生 > >python~正則表示式總結二

python~正則表示式總結二

目錄

編譯正則表示式

re.compile(pattern,flags=0)

pattern.match

pattern.search

pattern.findall

1.正則表示式無圓括號

2.正則表示式中含有1個圓括號

3.正則表示式中含有多個圓括號

pattern.split

pattern.sub

pattern.subn(repl,string,[count=0])

分組

無名分組

有名分組 (?P正則表示式)

一個命名分組

多個命名分組

後向引用

通過預設分組編號進行後向引用

通過命名分組進行後向引用(?P=name)

交換字串的位置

前向肯定斷言(?=pattern)與後向肯定斷言(?<=pattern)

前向否定斷言(?!pattern)與後向否定斷言(?<!pattern)


編譯正則表示式

re.compile(pattern,flags=0)

pattern類的工廠方法,目的是將正則表示式pattern編譯成pattern物件,並返回該物件。

將正則表示式編譯成一個正則表示式物件,這樣做可以提高效率;

第二個引數flag是匹配模式;

使用該pattern模式唯一的好處就是,一處編譯,多出複用;

pattern.match

函式作用:這個方法將在字串string的pos位置開始,嘗試匹配pattern(pattern就是通過re.compile()方法編譯後返回的物件),如果pattern匹配成功,無論是否達到結束位置endpos,都會返回一個匹配成功後的 Match物件;如果匹配不成功,或者 pattern未匹配結束就達到endpos,則返回None。   

引數說明:

string:被匹配的字串

pos:匹配的起始位置,可選,預設為0

endpos:匹配的結束位置,可選,預設為 len(string)   

匹配到的Match物件,我們將使用其具有的 group()方法取出匹配結果。

>>> import re

>>> pattern=re.compile(r"\d")   #編譯正則表示式

>>> pattern.match("123")

<_sre.SRE_Match object; span=(0, 1), match='1'>

>>> pattern.match("123").group()

'1'

>>> pattern.match("123",2).group()  #起始位置為2

'3'

>>> pattern.match("d23")     #匹配失敗

>>> print (pattern.match("d23"))

None

pattern.search

該方法的作用是在string[pos, endpos]區間從pos下標處開始匹配pattern,如果匹配成功,返回匹配成功的Match物件;如果沒有匹配成功,則將pos加1後重新嘗試匹配,直到 pos=endpos時仍無法匹配則返回None

引數說明:

string:被匹配的字串

pos:匹配的起始位置,可選,預設為0

endpos:匹配的結束位置,可選,預設為len(string)

也就是說如果不指定pos和endpos這兩個引數的話,該方法會掃描整個字串

>>> import re

>>> pattern=re.compile(r"\d+\s?")  

>>> pattern.search("we12 346")

<_sre.SRE_Match object; span=(2, 5), match='12 '>

>>> pattern.search("we12 346").group()

'12 '

>>> pattern.search("we12 346",5).group()

'346'

pattern.findall

函式作用: 該方法的作用是在string[pos, endpos]區間從pos下標處開始查詢所有滿足pattern的子串,直到endpos位置結束,並以列表的形式返回查詢的結果,如果未找到則返回一個空列表

引數說明:

string:被匹配的字串

pos:匹配的起始位置,可選,預設為0

endpos:匹配的結束位置,可選,預設為len(string)   --->開區間

也就是說如果不指定pos和endpos這兩個引數的話,該方法會在整個字串中查詢所有滿足 條件的子串。

1.正則表示式無圓括號

import re

"找到正則表示式匹配的前10個字母中的所有數字"
pattern=re.compile(r"\d+")

result=pattern.findall("adf324sdf34vsdaf5634",0,10)
print (result)

2.正則表示式中含有1個圓括號

import re

"查詢字串中所有的數字子串"
matchStr = 'adsd12343.jl34d5645fd789'
#pattern=re.compile(r".*?(\d+).*?")
pattern=re.compile(r"(\d+)")
result=pattern.findall(matchStr)
print (result)

#當正則表示式中只帶有一個圓括號時,列表中的元素為字串,並且該字串的內容與括號中的正則表示式相對應,並且整個返回的結果都是圓括號中的內容,而不是整個正則表示式匹配的內容

3.正則表示式中含有多個圓括號

import re

"提取字串中所有的有效的域名地址"
add = 'https://www.net.com.edu//action=?asdfsd and other https://www.baidu.com//a=b' 

pattern=re.compile(r"((w{3}\.)(\w+\.)+(com|edu|cn|net))")
result=pattern.findall(add)
print (result)


“提取字串中所有的網址”
import re

add = 'https://www.net.com.edu//action=?asdfsd and other https://www.baidu.com//a=b' 
pattern=re.compile(r"https://?w{3}\.\w+\.\w+\.?\w+")
result=pattern.findall(add)
print (result)	

pattern.split

pattern.split(string[, maxsplit = 0])

函式作用:  

分割字串,將字串string用給定的正則表示式匹配的字串進行分割,並返回分割後的結果list。  

引數說明:

string:被匹配的字串

maxsplit:用於指定最大分割次數,可選,預設為0,表示全部分割

import re

pattern=re.compile(r"\d+")
“不指定分割次數”
result=pattern.split("one1two2three3four4")
print (result[:-1])

“指定分割次數”
result1=pattern.split("one1two2three3four4",2)
print (result1)

pattern.sub

pattern.sub(repl, string[, count = 0])

引數說明:

repl:用於替換的字串

string:要被替換的字串

count:替換的次數,如果為0表示替換所有匹配到的字串,如果是1表示替換1次,為2替換2次等,該引數必須是非負整數,預設為0

import re

p = re.compile(r'(\w+) (\w+)')
s = "i say, hello world!"
print (p.sub(r"\2 \1",s))

def func(m):
    #print (m.group())
    return m.group(1).title() + ' ' + m.group(2).title()
    
print (p.sub(func, s))

pattern.subn(repl,string,[count=0])

subn用法和sub函式用法相似,不過結果返回一個tuple,tuple第一個元素是替換後的新字串,第二個元素是替換的次數

import re

p = re.compile(r'[^\w|\s]+')
"去掉語句加的特殊符號"
s = "^&&today&(is%%#fine# day!" 
result= p.subn(" ", s) 
print (result)
print ("替換後的新字串為%s" % result[0])
print ("替換次數為%s" % result[1])

分組

無名分組

分組就是用一對圓括號“()”括起來的正則表示式,匹配出的內容就表示一個分組。從正則表示式的左邊開始看,看到的第一個左括號“(”表示表示第一個分組,第二個表示第二個分組,依次類推。需要注意的是,有一個隱含的全域性分組(就是索引號為0的分組),就是整個正則表示式匹配的結果

import re   

s = u'<div><ahref="https://support.google.com/chrome/?p=ui_hotword_search" target="_blank">更多 </a><p>dfsl</p></div>' 

result=re.search(r"<a.*>(.*)</a>",s).group()
print (result)

result=re.search(r"<a.*>(.*)</a>",s).group(1)
print (result)

result1=re.match(r".*<a.*>(.*)</a>",s).group(1)  #與上面的正則表示式等價
print (result1)

有名分組 (?P<name>正則表示式)

一個命名分組

命名分組就是給具體有預設分組編號的組另外再起一個別名,方便以後的引用。

命令分組的語法格式如下:

(?P<name>正則表示式) 語法格式中的字元P必須是大寫的“P”,name是一個合法的識別符號,表示分組的別名。

“提取字串中的ip地址”
import re

s = "ip='230.192.168.78',version='1.0.0'" 
res = re.search(r"ip='(?P<ip>\d+\.\d+\.\d+\.\d+).*", s) 
print (res.group('ip'))   #通過命名分組引用分組 

多個命名分組

import re


s ="phone,number,15817934235"

result=re.search(r"(?P<Last>\w+),(?P<First>\w+),(?P<phone>\d+)",s)

print (result.group("Last"))   #取第一個分組的內容

print (result.group("First"))   #取第二個分組的內容

print (result.group("phone"))  #取第三個分組的內容

後向引用

正則表示式中,放在圓括號“()”中的表示是一個分組。然後我們就可以對整個組使用一些正則操作,例如重複操作符。

要注意的是,只有圓括號“()”才能用於形成分組,””用於定義字串,而”{}”用於定義重複操作。當用”()”定義了一個正則表示式分組後,正則引擎就會把匹配的組按照順序進行編號,然後存入快取中。這樣我們就可以在後面對已經匹配過的內容進行引用,這就叫後向引用。

後向引用的語法:

  1. 通過索引引用

\數字:\1表示引用第一個分組,\2引用第二個分組,以此類推,\n引用第n個組,而\0則表示引用整個被匹配的正則表示式本身。

  1. 通過命名分組名進行引用(如果有的話) 

(?P=name) 字元P必須是大寫的P,name表示命名分組的分組名。

注意:

這些引用都必須是在正則表示式中才有效,用於匹配一些重複的字串。

通過預設分組編號進行後向引用

import re
s = 'aaa111aaatestaaa'
print (re.findall(r'([a-z]+)\d+(\1).*(\1)', s))

通過命名分組進行後向引用(?P=name)

import re   
#後向引用,匹配兩個一樣的單詞,內容必須一致,否則匹配失敗
res = re.search(r'(?P<name>go)\s+(?P=name)\s+(?P=name)', 'go go go') 
#res=re.search(r"(\w+)\s(\1)\s(\2)",s)
print (res.group())
print (res.group('name')) 

交換字串的位置

import re

s="abc.xyz"
#交換.號兩邊的字串
result=re.sub(r"(.*)\.(.*)",r"\2.\1",s)
#result=re.sub(r"(\w+)\.(\w+)",r"\2.\1",s)
print (result)

前向肯定斷言(?=pattern)與後向肯定斷言(?<=pattern)

前向肯定斷言的語法:

(?=pattern) 前向肯定斷言表示你希望匹配的字串前面是pattern匹配的內容時,才匹配。

後向肯定斷言的語法:

(?<=pattern) 後向肯定斷言表示你希望匹配的字串的後面是pattern匹配的內容時,才匹配

如果在一次匹配過程中,需要同時用到前向肯定斷言和後向肯定斷言時,那必須將前向肯定斷言表示式寫在要匹配的正則表示式的前面,而後向肯定斷言表示式寫在要匹配的字串的後面,表示後向肯定模式之後,前向肯定模式之前

#匹配以a字母為開頭的單詞
>>> s="abc bcd aed"
>>> re.findall(r"\b(?=a)\w+\b",s)
['abc', 'aed']

#匹配以ing為結尾的單詞
>>> import re
>>> s="I'm singing while you're dancing"
>>> re.findall(r"\b\w+(?<=ing)\b",s)
['singing', 'dancing']

前向肯定斷言括號中的正則表示式必須是能確定長度的正則表示式,比如\w{3},而不能寫成 \w*或者\w+或者\w?等這種不能確定個數的正則模式符。

前向否定斷言(?!pattern)與後向否定斷言(?<!pattern)

前向否定斷言的語法:

(?!pattern) 前向否定斷言表示你希望匹配的字串的前面不是pattern匹配的內容時,才匹配。

後向否定斷言的語法:

(?<!pattern) 後向否定斷言表示你希望匹配的字串後面不是pattern匹配的內容時,才匹配。

#匹配開頭不是a的所有單詞
>>> import re
>>> s="abc bcd aed"
>>> re.findall(r"\b(?!a)\w+\b",s)
['bcd']


#匹配結尾不是K的所有單詞
>>> s="word work work wors"
>>> re.findall(r"\b\w+(?<!k)\b",s)
['word', 'wors']