re(正則表達式)模塊


一、最常用的匹配語法

re.match 從頭開始匹配

re.search 匹配包含

re.findall 把所有匹配到的字符放到以列表中的元素返回

re.split  以匹配到的字符當做列表分隔符

re.sub      匹配字符並替換
 
二、常用正則表達式符號
'.'        默認匹配除\n之外的任意一個字符,若指定flag DOTALL,則匹配任意字符,包括換行
'^'          匹配字符開頭,若指定flags MULTILINE,這種也可以匹配上(r "^a" , "\nabc\neee" ,flags = re.MULTILINE)
'$'          匹配字符結尾,或e.search( "foo$" , "bfoo\nsdfsf" ,flags = re.MULTILINE).group()也可以
'*'          匹配 * 號前的字符 0 次或多次,re.findall( "ab*" , "cabb3abcbbac" )  結果為[ 'abb' 'ab' 'a' ]
'+'          匹配前一個字符 1 次或多次,re.findall( "ab+" , "ab+cd+abb+bba" ) 結果[ 'ab' 'abb' ]
'?'          匹配前一個字符 1 次或 0
'{m}'       匹配前一個字符m次
'{n,m}'    匹配前一個字符n到m次,re.findall( "ab{1,3}" , "abb abc abbcbbb" ) 結果 'abb' 'ab' 'abb' ]
'|'          匹配|左或|右的字符,re.search( "abc|ABC" , "ABCBabcCD" ).group() 結果 'ABC'
'(...)'    分組匹配,re.search( "(abc){2}a(123|456)c" "abcabca456c" ).group() 結果 abcabca456c
'[]'            字符集,匹配括號內的所有字符
       
 
'\Z'     匹配字符結尾,同$
'\d'     匹配數字 0 - 9
'\D'     匹配非數字
'\w'     匹配[A - Za - z0 - 9 ]
'\W'     匹配非[A - Za - z0 - 9 ]
's'      匹配空白字符、\t、\n、\r , re.search( "\s+" , "ab\tc1\n3" ).group() 結果  '\t'
 
'(?P<name>...)'  分組匹配 re.search( "(?P<province>[0-9]{4})(?P<city>[0-9]{2})(?P<birthday>[0-9]{4})" , "371481199306143242" ).groupdict( "city" ) 結果{ 'province' '3714' 'city' '81' 'birthday' '1993' }
 
三、符號詳解
下面只針對python的re模塊,其他語言的我沒有測試過
1、+號:+號是匹配前一個規則一次或多次,即在匹配字符中至少要匹配前一個規則一次,如果一次都沒有匹配,則算匹配失敗
2、*號:*號匹配前一個規則0次或多次,即可以匹配不到
例子:
如:一個字符串中可能有空格,可能沒有空格,但是結果都是我們需要的值,那我們就需要*號。如匹配數字,我們至少要匹配一次,否則就不是我們要的結果,這里就不能用*,下面是匹配算術表達式的一個例子
import re
a = 'abc+10 + 20'
b = 'abc+10+20'
regex1 = re.compile('\d+\s*[+]\s*\d+') #對正則表達式進行編譯,\d+表示匹配一個或多個數字,\s*表示匹配0個或多個空格,[]里面為字符集
print(regex1.search(a).group()) #匹配字符串 結果:10 + 20,對匹配該算術表達式來說,如果這里換成\s+則匹配不到,如果\d+換成\d*則會匹配到你不想匹配到的結果
print(regex1.search(b).group())        #結果:10+20

上述的python表示方式也可以這么表示
print(re.search('\d+\s*[+]\s*\d+',a).group())等同於先進行編譯,再匹配
3、?一般搭配*、+、{}使用

當正則表達式中包含能接受重復的限定符時,通常的行為是(在使整個表達式能得到匹配的前提下)匹配盡可能多的字符。以這個表達式為例:a.*b,它將會匹配最長的以a開始,以b結束的字符串。如果用它來搜索aabab的話,它會匹配整個字符串aabab。這被稱為貪婪匹配。

有時,我們更需要懶惰匹配,也就是匹配盡可能少的字符。前面給出的限定符都可以被轉化為懶惰匹配模式,只要在它后面加上一個問號?。這樣.*?就意味着匹配任意數量的重復,但是在能使整個匹配成功的前提下使用最少的重復。現在看看懶惰版的例子吧:

a.*?b匹配最短的,以a開始,以b結束的字符串。如果把它應用於aabab的話,它會匹配aab(第一到第三個字符)和ab(第四到第五個字符)。

python結果:
a = 'aabab'
regex1 = re.compile(r'a.*?b')
regex2 = re.compile(r'a.*b')

print(regex1.findall(a)) ->['aab', 'ab'] ->這里用search的話只能找到aab
print(regex2.findall(a)) ->['aabab']

 "*?"   重復任意次,但盡可能少重復 

      如 "acbacb"  正則  "a.*?b" 只會取到第一個"acb" 原本可以全部取到但加了限定符后,只會匹配盡可能少的字符 ,而"acbacb"最少字符的結果就是"acb" 

  "+?"  重復1次或更多次,但盡可能少重復

     與上面一樣,只是至少要重復1次

  "??"  重復0次或1次,但盡可能少重復

      如 "aaacb" 正則 "a.??b" 只會取到最后的三個字符"acb"

  "{n,m}?"  重復n到m次,但盡可能少重復

          如 "aaaaaaaa"  正則 "a{0,m}" 因為最少是0次所以取到結果為空

  "{n,}?"    重復n次以上,但盡可能少重復

          如 "aaaaaaa"  正則 "a{1,}" 最少是1次所以取到結果為 "a"



4、groups與()搭配使用
a = 'abc+10+20'
regex1 = re.compile(r'(\d+)([+])(\d+)')
print(regex1.search(a).groups()) ->('10', '+', '20') 能把分組的數據一一取出來

5、^與&
如:匹配以數字開頭以數字結尾
a = '1abc+10+20'
regex1 = re.compile(r'^\d.*\d$')
print(regex1.search(a).group()) ->1abc+10+20,如果不是以數字開頭和數字結尾則匹配不到
6、groupdict與()搭配使用
print(re.search("(?P<province>[0-9]{4})(?P<city>[0-9]{2})(?P<birthday>[0-9]{4})","371481199306143242").groupdict() ) -> {'province': '3714', 'city': '81', 'birthday': '1993'}
7、split使用
  1. a = '1abc+10+20'
  2. regex1 = re.compile(r'\+')
  3. print(regex1.split(a)) ->['1abc', '10', '20']

上述2、3步驟相當於
print(re.split(r'\+',a))

8、sub使用
*號替換+號
  1. a = '1abc+10+20'
  2. regex1 = re.compile(r'\+')
  3. print(regex1.sub('*',a)) ->1abc*10*20,后面可以加count來確保匹配多少次
上述2、3步驟相當於

#print(re.sub(r'\+','*',a)) ->1abc*10*20


9、反斜杠的困擾
與大多數編程語言相同,正則表達式里使用"\"作為轉義字符,這就可能造成反斜杠困擾。假如你需要匹配文本中的字符"\",那么使用編程語言表示的正則表達式里將需要4個反斜杠"\\\\":前兩個和后兩個分別用於在編程語言里轉義成反斜杠,轉換成兩個反斜杠后再在正則表達式里轉義成一個反斜杠。Python里的原生字符串很好地解決了這個問題,這個例子中的正則表達式可以使用r"\\"表示。同樣,匹配一個數字的"\\d"可以寫成r"\d"。有了原生字符串,你再也不用擔心是不是漏寫了反斜杠,寫出來的表達式也更直觀。

10^與[]搭配

[^abc]匹配除了abc之外的任意字符
最后在添加一個圖表

 




免責聲明!

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



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