python re模塊與正則

1. re模塊

1.1 轉義符

正則表達式中的轉義符在python的字符串中也恰好有轉移的做用,可是正則表達式中的轉義符和字符串中的轉義符並不要緊,且還容易有衝突。
爲了不這種衝突,咱們全部的正則都以在工具中的測試結果爲結果,而後只須要在正則和待匹配的字符串外面都加r便可python

print('\\\\n')   # \\n
print('\\n')     # \n

print(r'\\n')    # \\n
print(r'\n')     # \n

1.2re模塊的方法

1.2.1 re.findall()

findall 會匹配字符串中全部符合規則的項,並返回一個列表,若是未匹配到,則返回空列表。正則表達式

import re

ret = re.findall('\d+','alex83')
print(ret)

1.2.2 re.search()

search 會從頭至尾從帶匹配匹配字符串中取出第一個符合條件的項,若是匹配到了,返回一個對象,用group取值;若是沒匹配到,返回None,不能用group取值。工具

import re

ret = re.search('\d+','alex83')
print(ret)  # 若是能匹配上返回一個對象,若是不能匹配上返回None
if ret:
    print(ret.group()) # 若是是對象,那麼這個對象內部實現了group,因此能夠取值
                       # 若是是None,那麼這個對象不可能實現了group方法,因此報錯

1.2.3 re.match()

match 會從頭匹配字符串中取出從第一個字符開始是否符合規則,若是符合,就返回對象,用group取值;若是不符合,就返回None.測試

match = search + ^正則code

import re

ret = re.match('\d','alex83') == re.match('^\d','alex83')
print(ret)

1.2.4 進階方法

  • 1.時間複雜度 效率 compile對象

    在同一個正則表達式重複使用屢次的時候使用可以減小時間的開銷內存

  • 2.空間複雜度 內存佔用率 finditerrem

    在查詢的結果超過1個的狀況下,可以有效的節省內存,下降空間複雜度,從而也下降了時間複雜度字符串

  • 3.用戶體驗it

1.2.5 re.finditer()

import re

ret = re.findall('\d','safhl02urhefy023908'*20000000)  # 時間複雜度、空間複雜度都很是高
print(ret)

ret = re.finditer('\d','safhl02urhefy023908'*20000000)  # ret是迭代器
for i in ret:    # 迭代出來的每一項都是一個對象
    print(i.group())  # 經過group取值便可

1.2.6 re.compile()

import re

ret = re.compile('\d3')  # 先配置好正則
print(ret)
r1 = ret.search('alex83')  # 能夠直接調用
print(r1)
ret.findall('wusir74')

ret = re.compile('\d+')
r3 = ret.finditer('taibai40')
for i in r3:
    print(i.group())

\d 正則表達式  ——> 字符串
    \d  str
        循環str,找到全部的數字

1.2.7 re.split() 切割

import re

ret = re.split('\d+','alex83wusir74taibai')
print(ret)  # ['alex', 'wusir', 'taibai']

ret = re.split('\d(\d)','alex83wusir74taibai')  # 默認自動保留分組中的內容(被切割掉的內容)
print(ret)  # ['alex', '3', 'wusir', '4', 'taibai']

1.2.8 re.sub() / re.subn() 替換

import re

ret = re.sub('\d','D','alex83wusir74taibai',1)
print(ret)  # alexD3wusir74taibai

ret = re.sub('\d','D','alex83wusir74taibai',3)  # 3表示替換掉幾個
print(ret)  # alexDDwusirD4taibai

ret = re.subn('\d','D','alex83wusir74taibai')  # subn 直接所有替換的
print(ret)  # ('alexDDwusirDDtaibai', 4)  # 獲得一個元組,並把一共替換掉幾個做爲元組的一個元素

1.3 分組的概念和re模塊

1.3.1 分組命名

s1 = '<h1>wahaha</h1>'
s2 = '<a>wahaha ya wahaha</a>'
# s1 -> h1  wahaha
# s2 -> a   wahaha ya wahaha
import re

# 方法一
ret = re.search('<(\w+)>(.*?)</\w+>',s1)
print(ret)
print(ret.group(0))   # group參數默認爲0 表示取整個正則匹配的結果
print(ret.group(1))   # 取第一個分組中的內容
print(ret.group(2))   # 取第二個分組中的內容

# 方法二(分組命名)
ret = re.search('<(?P<tag>\w+)>(?P<cont>.*?)</\w+>',s1)
print(ret)
print(ret.group('tag'))   # 取tag分組中的內容
print(ret.group('cont'))   # 取cont分組中的內容

分組命名:

(?P <名字> 正則表達式)

1.3.2 引用分組

引用分組 (?P=組名) 這個組中的內容必須徹底和以前已經存在的組匹配到的內容如出一轍

s1 = '<h1>wahaha</h1>'
s2 = '<a>wahaha ya wahaha</a>'
ret = re.search('<(?P<tag>\w+)>.*?</(?P=tag)>',s1)  # 用於約束先後<>內的內容一致
print(ret.group('tag'))  # h1

# \1:轉義1,表示分組中的
s1 = '<h1>wahaha</h1>'
s2 = '<a>wahaha ya wahaha</a>'
ret = re.search(r'<(\w+)>.*?</\1>',s1)
print(ret.group(1))  # h1

findall 遇到分組

findall 遇到正則表達式中的分組,會優先顯示分組中的內容

import re

ret = re.findall('\d(\d)','aa1alex83')
# findall遇到正則表達式中的分組,會優先顯示分組中的內容
print(ret)

ret = re.findall('\d+(?:\.\d+)?','1.234+2')  # ?: 取消分組優先顯示
print(ret)

分組和 findall

  • 默認findall 優先顯示分組內的內容
  • 取消分組優先顯示 (?:正則)
# 例題
  # 有的時候咱們想匹配的內容包含在不相匹配的內容當中,這個時候只須要把不想匹配的先匹配出來,再經過手段去掉
import re
ret=re.findall(r"\d+\.\d+|(\d+)","1-2*(60+(-40.35/5)-(-4*3))")
print(ret)
ret.remove('')
print(ret)

split 遇到分組:會保留分組中原本應該被切割掉的內容

1.4 生成器的send方法

def func():
    print(123)
    n = yield 'aaa'
    print('-->',n)
    yield 'bbb'

g = func()
print(g)
n = next(g)
print(n)
print('-'*20)
next(g)   # g.send('uysdfhfoiusyg')與next(g)的做用同樣

1.5 小總結

正則 ?都能作什麼?

    1. ?表示匹配0次或1次 表示無關緊要 可是有隻能有一個 好比小數點
    2. 用於非貪婪匹配:.*?x 匹配任意的內容任意屢次遇到x就當即中止
    3. 分組命名: (?P <名字> 正則表達式)
    4. 引用分組: (?P=組名)
    5. findall 遇到正則表達式中的分組時,?: 取消分組優先顯示
相關文章
相關標籤/搜索