一、常用的匹配規(guī)則總結(jié):
| 模式 | 描述 |
|---|---|
\w |
匹配字母數(shù)字及下劃線 |
\W |
匹配非字母數(shù)字及下劃線 |
\s |
匹配任意空白字符,等價于 [\t\n\r\f]. |
\S |
匹配任意非空字符 |
\d |
匹配任意數(shù)字,等價于 [0-9] |
\D |
匹配任意非數(shù)字 |
\A |
匹配字符串開始 |
\Z |
匹配字符串結(jié)束,如果是存在換行,只匹配到換行前的結(jié)束字符串 |
\z |
匹配字符串結(jié)束 |
\G |
匹配最后匹配完成的位置 |
\n |
匹配一個換行符 |
\t |
匹配一個制表符 |
^ |
匹配字符串的開頭 |
$ |
匹配字符串的末尾 |
. |
匹配任意字符,除了換行符,當(dāng) re.DOTALL 標(biāo)記被指定時,則可以匹配包括換行符的任意字符 |
[...] |
用來表示一組字符,單獨列出:[amk] 匹配 'a','m' 或 'k' |
[^...] |
不在 [] 中的字符:匹配除了 a,b,c 之外的字符。 |
* |
匹配 0 個或多個的表達(dá)式。 |
+ |
匹配 1 個或多個的表達(dá)式。 |
? |
匹配 0 個或 1 個由前面的正則表達(dá)式定義的片段,非貪婪方式 |
{n} |
精確匹配 n 個前面表達(dá)式。 |
{n, m} |
匹配 n 到 m 次由前面的正則表達(dá)式定義的片段,貪婪方式 |
a l b |
匹配 a 或 b(中間是分隔符) |
( ) |
匹配括號內(nèi)的表達(dá)式,也表示一個組 |
二、萬能匹配符號
.(點)可以匹配任意字符(除換行符),*(星) 又代表匹配前面的字符無限次,所以它們組合在一起 .* 就可以匹配任意的字符了,有了它我們就不用挨個字符地匹配了。
貪婪匹配:.* 可以匹配任意多的字符,在正常它會盡量多地匹配字符,如下實例:
import re
content = 'Hello 1234567 World_This is a Regex Demo'
result = re.match('^He.*(\d+).*Demo$', content)
print(result.group(1))
# 結(jié)果是 7
#匹配式'^He.*(\d+).*Demo$' 中.*(貪婪匹配)可以盡量多地匹配到llo 123456 而正則式仍成立的
非貪婪的匹配:這時要想得到一個非貪婪的匹配,可以得到1234567,可以用.*? 為非貪婪匹配模式。實例如下:
import re
content = 'Hello 1234567 World_This is a Regex Demo'
result = re.match('^He.*?(\d+).*Demo$', content)
print(result.group(1))
# 結(jié)果是 1234567
貪婪匹配是盡可能匹配多的字符,非貪婪匹配就是盡可能匹配少的字符.*? 之后是 \d+ 用來匹配數(shù)字,當(dāng) .*?匹配到 Hello 后面的空白字符的時候,再往后的字符就是數(shù)字了,而 \d+ 恰好可以匹配,那么這里.*?就不再進(jìn)行匹配,交給 \d+ 去匹配后面的數(shù)字。所以.*?匹配了盡可能少的字符,\d+ 的結(jié)果就是 1234567 。
三、修飾符
| 修飾符 | 描述 |
|---|---|
| re.I | 使匹配對大小寫不敏感 |
| re.L | 做本地化識別(locale-aware)匹配 |
| re.M | 多行匹配,影響 ^ 和 $ |
| re.S或者re.DOTALL | 使點 . 可以匹配包括換行在內(nèi)的所有字符 |
| re.U | 根據(jù)Unicode字符集解析字符。這個標(biāo)志影響 \w, \W, \b, \B. |
| re.X | 該標(biāo)志通過給予你更靈活的格式以便你將正則表達(dá)式寫得更易于理解。 |
在網(wǎng)頁匹配中較為常用的為 re.S、re.I。
實例:
import re
content = '''Hello 1234567 World_This
is a Regex Demo
'''
result = re.match('^He.*?(\d+).*?Demo$', content)
print(result.group(1))
#運行結(jié)果:AttributeError: 'NoneType' object has no attribute 'group',沒有捕獲括號內(nèi)的值
因為需求匹配的文本content有換行符(有換行),而. 匹配的是換行符以外的任意字符,故匹配失敗。那么在這里我們只需要加一個修飾符 re.S,即可修正這個錯誤。
result = re.match('^He.*?(\d+).*?Demo$', content, re.S)
#運行結(jié)果:1234567
#在 match() 方法的第三個參數(shù)傳入 re.S,它的作用是使 . 匹配包括換行符在內(nèi)的所有字符。
四、re庫函數(shù)
- re.match():從字符串的開頭開始匹配,匹配到相符的;
import re
content = 'Extra stings Hello 1234567 World_This is a Regex Demo Extra stings'
result = re.match('Hello.*?(\d+).*?Demo', content)
print(result)
#運行結(jié)果 None
- re.search():匹配時會掃描整個字符串,然后返回第一個成功匹配的結(jié)果;
import re
content = 'Extra stings Hello 1234567 World_This is a Regex Demo Extra stings'
result = re.search('Hello.*?(\d+).*?Demo', content)
print(result)
#運行結(jié)果 <_sre.SRE_Match object; span=(13, 53), match='Hello 1234567 World_This is a Regex Demo'>
re.findall():匹配時會掃描整個字符串,然后返回匹配正則表達(dá)式的所有內(nèi)容;
re.sub():匹配到整個字符串符合的內(nèi)容,并做替換;
import re
content = '54aK54yr5oiR54ix5L2g'
content = re.sub('\d+', '', content)
print(content)
#結(jié)果:aKyroiRixLg
#re.sub(‘正則式’,‘替換內(nèi)容’,驗證的文本)
- re.compile():將正則字符串編譯成正則表達(dá)式對象,以便于在后面的匹配中復(fù)用;
import re
content1 = '2016-12-15 12:00'
content2 = '2016-12-17 12:55'
content3 = '2016-12-22 13:21'
pattern = re.compile('\d{2}:\d{2}')
result1 = re.sub(pattern, '', content1)
result2 = re.sub(pattern, '', content2)
result3 = re.sub(pattern, '', content3)
print(result1, result2, result3)
#運行結(jié)果:2016-12-15 2016-12-17 2016-12-22
#將正則字符串編譯成正則表達(dá)式對象pattern,后面直接調(diào)用pattern
參考資料:
正則表達(dá)式: [https://germey.gitbooks.io/python3webspider/3.3-%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F.html]
在線正則表達(dá)式測試:http://tool.oschina.net/regex/#