正則表達式
一、定義
regular expression 用於檢索、替換、匹配驗證字符串。
開源中國正則表達式測試工具:https://tool.oschina.net/regex
一個URL:http://www.baidu.com
正則表達式爲
[…]匹配一組字符串,[ab]匹配a,b,ab
[a-zA-Z]匹配英文字母
[^/s]匹配一組非空白字符串
*匹配多個
二、常用匹配規則
字符匹配
\w | 匹配字母、數字、下劃線,剛好是代碼裏要求的字符 |
---|---|
\W | 匹配非字母、數字、下劃線的字符 |
\s | space 任意空格,等價於[/r/n/t/f] |
\S | 匹配非空格字符 |
\d | digital匹配數字 |
\D | 匹配非數字字符 |
\n | 匹配換行符 |
\t | 匹配tab |
^ | 匹配一行字符串的開頭 |
$ | 匹配一行字符串的結尾 |
數量限制
* | [0,無窮大] |
---|---|
+ | [1,無窮大] |
? | [0,1]問號,有還是沒有,所以取值範圍爲[0,1] |
[] | 匹配一組字符串,[ab],匹配a,b,ab |
[^] | 匹配一組字符串,[^a 匹配不含a 的字符串 |
{n} | 匹配n個前面的表達式 |
{n,m} | 匹配 n 到 m 次由前面正則表達式定義的片段,貪婪方式 |
a|b | 匹配 a或b |
() | 匹配括號內的表達式,也表示一個組 |
. | 匹配除換行符以外的所有字符 |
三、常用修飾符
re.S | 使匹配對大小寫不敏感 |
---|---|
re.I | 做本地化識別(local-aware)匹配 |
re.M | 多行匹配,影響^ $ ,Multiline |
re.S | 使.匹配包換換行符在內的字符 |
re.U | 根據Unicode字符集解析字符,影響\w,\W,\b,\B |
re.X | 該標誌通過給予你更靈活的格式以便你將正則表達式寫得更易於理解 |
四、代碼
import re
#vscode快捷鍵
# control+b 隱藏,顯示右邊欄
#control+k+0完全摺疊代碼
# control+k+j完全展開代碼
# control+shift+k 刪除當前行
# alt +shift +up/down 複製當前行
#match(正則表達式,content)
def re_match():
'''input:正則表達式,待匹配字符串
output:匹配成功則輸出匹配結果對象,負責None
從待匹配字符串的第一個開始匹配'''
content="Hello 123 4567 World_This is a Regex Demo "
result=re.match('^Hello\s\d\d\d\s\d{4}\s\w{10}',content)
print(len(content))
print(result)
#re.Match object有兩個函數
#group輸出匹配的字符串
print(result.group())
#span()輸出匹配範圍
print(result.span())
#使用match匹配目標,提取一段數字
#()實際上標記了一個子表達式的開始和結束位置,
# 被標記的每個子表達式會依次對應每一個分組,
# 調用 group()方法傳入分組的索引即可獲取提取的結果
def match_number():
'目標匹配match匹配一段數字'
content='Hello 949374707 mingyue World'
result=re.match('^Hello\s(\d+)\s(\w+)\s(\w+)',content)
print(result)
print(result.group())
print(result.group(1))
print(result.group(2))
print(result.group(3))
#通用匹配之點心 .*
def general_match():
content='Hello mingyue 12345 this is a regex Demo'
regex='^Hello.*Demo$'
result=re.match(regex,content)
print(result)
print(result.group())
print(result.span())
#.*貪婪匹配儘可能匹配多的字符,.*?非貪婪匹配儘可能匹配少的字符
def greedy_match():
content='hello 123345 what is worth doing is worth doing well'
#貪婪匹配
regex1='^hello(.*)well$'
#非貪婪匹配
regex2='^hello(.*?)'
result1=re.match(regex1,content)
result2=re.match(regex2,content)
print(result1)
print(result1.group())
print(result1.group(1))
print('-----------------')
print(result2)
print(result2.group())
#修飾符的使用
#.*遇到換行符就無法匹配了,how?
def ornament():
content='''i am the sword
in the night'''
regex='^i.*night$'
result=re.match(regex,content,re.S)
print(result)
#轉義匹配
def zhuanyi_match():
content='(百度)www.baidu.com'
regex='\(百度\)www\.baidu\.com'
result=re.match(regex,content)
print(result)
print(result.group())
print(result.span())
#search()匹配HTML代碼
def search_html():
'''match()從文本的開頭開始匹配,
search()搜索整個文本,返回與之匹配的第一個,
否則返回None'''
html='''
<li data-view="4" class="active">
<a href="/3.mp3" singer="齊秦">往事隨風</a>
</li>'''
regex='<li.*?active.*?singer="(.*?)">(.*?)</a>'
result=re.search(regex,html,re.S)
if result:
print(result)
print(result.group())
print(result.group(1))
print(result.group(2))
#findall方法
def re_findall():
'''findall()返回所有匹配的字符
返回結果爲列表,列表中的每個元素是元組'''
html='''
<li data-view="4" class="active">
<a href="/3.mp3" singer="齊秦">往事隨風</a>
</li>'''
regex='<li.*?active.*?singer="(.*?)">(.*?)</a>'
result=re.findall(regex,html,re.S)
if result:
print(type(result))
print(result)
for i in result:
print(i)
#sub()去掉文本里的全部數字
def re_sub():
'''sub(regex,替換爲的字符,content)'''
content='123mingyue456for better you789'
regex='\d+'
content=re.sub(regex,'',content)
print(content)
#compile()
def re_compile():
'''compile將正則表達式編譯爲一個正則表達式對象
以便重複使用
pattern=re.compile(regex,修飾符)'''
content1='2018-12-26 12:00'
content2='2019-02-06 01:00'
content3='2018-03-28 02:00'
pattern=re.compile('\d{2}:\d{2}')
result1=re.sub(pattern,'',content1)
result2=re.sub(pattern,'',content2)
result3=re.sub(pattern,'',content3)
print(result1)
print(result2)
print(result3)
if __name__ == "__main__":
#re_match()
#match_number()
#general_match()
#greedy_match()
#ornament()
#zhuanyi_match()
#search_html()
#re_findall()
#re_sub()
re_compile()