python~正則表示式總結二
目錄
pattern.subn(repl,string,[count=0])
前向肯定斷言(?=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表示引用第一個分組,\2引用第二個分組,以此類推,\n引用第n個組,而\0則表示引用整個被匹配的正則表示式本身。
- 通過命名分組名進行引用(如果有的話)
(?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']