一.常用正則表達式符號和語法:
'.' 匹配所有字符串,除\n以外
‘-’ 表示范圍[0-9]
'*' 匹配前面的子表達式零次或多次。要匹配 * 字符,請使用 \*。
'+' 匹配前面的子表達式一次或多次。要匹配 + 字符,請使用 \+
'^' 匹配字符串開頭
‘$’ 匹配字符串結尾 re
'\' 轉義字符, 使后一個字符改變原來的意思,如果字符串中有字符*需要匹配,可以\*或者字符集[*] re.findall(r'3\*','3*ds')結['3*']
'*' 匹配前面的字符0次或多次 re.findall("ab*","cabc3abcbbac")結果:['ab', 'ab', 'a']
‘?’ 匹配前一個字符串0次或1次 re.findall('ab?','abcabcabcadf')結果['ab', 'ab', 'ab', 'a']
'{m}' 匹配前一個字符m次 re.findall('cb{1}','bchbchcbfbcbb')結果['cb', 'cb']
'{n,m}' 匹配前一個字符n到m次 re.findall('cb{2,3}','bchbchcbfbcbb')結果['cbb']
'\d' 匹配數字,等於[0-9] re.findall('\d','電話:10086')結果['1', '0', '0', '8', '6']
'\D' 匹配非數字,等於[^0-9] re.findall('\D','電話:10086')結果['電', '話', ':']
'\w' 匹配字母和數字,等於[A-Za-z0-9] re.findall('\w','alex123,./;;;')結果['a', 'l', 'e', 'x', '1', '2', '3']
'\W' 匹配非英文字母和數字,等於[^A-Za-z0-9] re.findall('\W','alex123,./;;;')結果[',', '.', '/', ';', ';', ';']
'\s' 匹配空白字符 re.findall('\s','3*ds \t\n')結果[' ', '\t', '\n']
'\S' 匹配非空白字符 re.findall('\s','3*ds \t\n')結果['3', '*', 'd', 's']
'\A' 匹配字符串開頭
'\Z' 匹配字符串結尾
'\b' 匹配單詞的詞首和詞尾,單詞被定義為一個字母數字序列,因此詞尾是用空白符或非字母數字符來表示的
'\B' 與\b相反,只在當前位置不在單詞邊界時匹配
'(?P<name>...)' 分組,除了原有編號外在指定一個額外的別名 re.search("(?P<province>[0-9]{4})(?P<city>[0-9]{2})(?P<birthday>[0-9]{8})","371481199306143242").groupdict("city") 結果{'province': '3714', 'city': '81', 'birthday': '19930614'}
[] 是定義匹配的字符范圍。比如 [a-zA-Z0-9] 表示相應位置的字符要匹配英文字符和數字。[\s*]表示空格或者*號。
二.常用的re函數:
方法/屬性 | 作用 |
re.match(pattern, string, flags=0) | 從字符串的起始位置匹配,如果起始位置匹配不成功的話,match()就返回none |
re.search(pattern, string, flags=0) | 掃描整個字符串並返回第一個成功的匹配 |
re.findall(pattern, string, flags=0) | 找到RE匹配的所有字符串,並把他們作為一個列表返回 |
re.finditer(pattern, string, flags=0) | 找到RE匹配的所有字符串,並把他們作為一個迭代器返回 |
re.sub(pattern, repl, string, count=0, flags=0) | 替換匹配到的字符串 |
函數參數說明:
pattern:匹配的正則表達式
string:要匹配的字符串
flags:標記為,用於控制正則表達式的匹配方式,如:是否區分大小寫,多行匹配等等。
repl:替換的字符串,也可作為一個函數
count:模式匹配后替換的最大次數,默認0表示替換所有匹配
例子1
#!/usr/bin/python3 import re #替換 phone = '18898537584 #這是我的電話號碼' print('我的電話號碼:',re.sub('#.*','',phone)) #去掉注釋 print(re.sub('\D','',phone)) #search ip_addr = re.search('(\d{3}\.){1,3}\d{1,3}\.\d{1,3}',os.popen('ifconfig').read()) print(ip_addr) #match >>> a = re.match('\d+','2ewrer666dad3123df45') >>> print(a.group()) 2
獲取匹配的函數:
方法/屬性 | 作用 |
group(num=0) | 匹配的整個表達式的字符串,group() 可以一次輸入多個組號,在這種情況下它將返回一個包含那些組所對應值的元組。 |
groups() | 返回包含所有小組字符串的元組,從1到所含的小組 |
groupdict() | 返回以有別名的組的別名為鍵、以該組截獲的子串為值的字典 |
start() | 返回匹配開始的位置 |
end() | 返回匹配結束的位置 |
span() | 返回一個元組包含匹配(開始,結束)的位置 |
三.原生字符串,字符,分組
1.原生字符串
每一次在匹配規則前面加了一個r,表示不轉義,使用原生字符串,沒用原始字符串,也沒出現什么問題。那是因為ASCII 里沒有對應的特殊字符,所以正則表達式編譯器能夠知道你指的是一個十進制數字。但是我們寫代碼本着嚴謹簡單的原理,最好是都寫成原生字符串的格式。
import re # “\b”在ASCII 字符中代表退格鍵,\b”在正則表達式中代表“匹配一個單詞邊界” print(re.findall("\bblow", "jason blow cat")) # 這里\b代表退格鍵,所以沒有匹配到 print(re.findall("\\bblow", "jason blow cat")) # 用\轉義后這里就匹配到了 ['blow'] print(re.findall(r"\bblow", "jason blow cat")) # 用原生字符串后就不需要轉義了 ['blow'] #執行結果: [] ['blow'] ['blow']
2.編譯
如果一個匹配規則要多次使用,可以先將其編譯,以后就不用每次去重復寫匹配規則:
import re comp = re.compile(r'\d') print(comp.findall('abc1213,-45'))
#執行結果
['1', '2', '1', '3', '4', '5'
3.分組
re模塊中分組的作用?
(1)判斷是否匹配(2)靈活提取匹配到各個分組的值。
>>> import re
>>> print(re.search(r'(\d+)-([a-z])','34324-dfsdfs777-hhh').group(0))
#返回整體
34324-d
>>> print(re.search(r'(\d+)-([a-z])','34324-dfsdfs777-hhh').group(1))
#返回第一組
34324
>>> print(re.search(r'(\d+)-([a-z])','34324-dfsdfs777-hhh').group(2))
#獲取第二組
d
>>> print(re.search(r'(\d+)-([a-z])','34324-dfsdfs777-hhh').group(3))
#不存在。報錯“no such group”
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: no such group