什么是正則
正則運算式是對字串(包括普通字符(例如,a 到 z 之間的字母)和特殊字符(稱為元字符))操作的一種邏輯公式,就是用事先定義好的一些特定字符、及這些特定字符的組合,組成一個規則字串,這個規則字串用來表達對字串的一種過濾邏輯,正則運算式是一種文本模式,該模式描述在搜索文本時要匹配的一個或多個字串,
作用
1 快速高效的查找與分析字串 2 進行有規律查找比對字串,也叫:模式匹配 3 具有查找、比對、匹配、替換、插入、添加、洗掉等能力,
字串是編程時涉及到的最多的一種資料結構,對字串進行操作的需求幾乎無處不在,比如我們撰寫爬蟲收集資料,首先都得到網頁原始碼,但是我們要如何提取有效資料呢,這時候我們就需要使用正則運算式來進行匹配了
Python中的正則—— re模塊
正則運算式中,使用 \ 表示轉義,這與原生的Python 行為是一致的,但是使用正則匹配時,應先進行Python原生字串的轉義,之后進行re 的轉義,
s = 'I\'m monkey!'
x = re.compile('I\'m monkey!') #
ret = x.findall(s)
print(ret)
x = re.compile('I\\\'m monkey!') # 在表示正則的字符中 兩個// 表示 正則運算式中的一個/ 因為要先經過Python字符轉義 會少一個
ret = x.findall(s)
print(ret) # 兩次結果一致
re中的符號和法則
正則運算式由特殊的語法,這個運算式也稱為 模式字串
字母和數字表示他們自身,一個正則運算式模式中的字母和數字匹配同樣的字串,
多數字母和數字前加一個反斜杠時會擁有不同的含義,
標點符號只有被轉義時才匹配自身,否則它們表示特殊的含義,
反斜杠本身需要使用反斜杠轉義,
盡可能的使用 ‘r’ 前綴表示字串,像這樣的方式 r'I'm Monkey'
下表列出了正則運算式模式語法中的特殊元素,如果你使用模式的同時提供了可選的標志引數,某些模式元素的含義會改變,
| 模式 | 描述 |
|---|---|
| ^ | 匹配字串的開頭 |
| $ | 匹配字串的末尾, |
| . | 匹配任意字符,除了換行符,當re.DOTALL標記被指定時,則可以匹配包括換行符的任意字符, |
| [...] | 用來表示一組字符,單獨列出:[amk] 匹配 'a','m'或'k' |
| [^...] | 不在[]中的字符:[^abc] 匹配除了a,b,c之外的字符, |
| re* | 匹配0個或多個的運算式, |
| re+ | 匹配1個或多個的運算式, |
| re? | 匹配0個或1個由前面的正則運算式定義的片段,非貪婪方式 |
| re{ n} | 匹配n個前面運算式,例如,"o{2}"不能匹配"Bob"中的"o",但是能匹配"food"中的兩個o, |
| re{ n,} | 精確匹配n個前面運算式,例如,"o{2,}"不能匹配"Bob"中的"o",但能匹配"foooood"中的所有o,"o{1,}"等價于"o+","o{0,}"則等價于"o*", |
| re{ n, m} | 匹配 n 到 m 次由前面的正則運算式定義的片段,貪婪方式 |
| a|b | 匹配a或b |
| (re) | 匹配括號內的運算式,也表示一個組 |
| (?imx) | 正則運算式包含三種可選標志:i, m, 或 x ,只影響括號中的區域, |
| (?-imx) | 正則運算式關閉 i, m, 或 x 可選標志,只影響括號中的區域, |
| (?: re) | 類似 (...), 但是不表示一個組 |
| (?imx: re) | 在括號中使用i, m, 或 x 可選標志 |
| (?-imx: re) | 在括號中不使用i, m, 或 x 可選標志 |
| (?#...) | 注釋. |
| (?= re) | 前向肯定界定符,如果所含正則運算式,以 ... 表示,在當前位置成功匹配時成功,否則失敗,但一旦所含運算式已經嘗試,匹配引擎根本沒有提高;模式的剩余部分還要嘗試界定符的右邊, |
| (?! re) | 前向否定界定符,與肯定界定符相反;當所含運算式不能在字串當前位置匹配時成功, |
| (?> re) | 匹配的獨立模式,省去回溯, |
| \w | 匹配數字字母下劃線 |
| \W | 匹配非數字字母下劃線 |
| \s | 匹配任意空白字符,等價于 [\t\n\r\f], |
| \S | 匹配任意非空字符 |
| \d | 匹配任意數字,等價于 [0-9], |
| \D | 匹配任意非數字 |
| \A | 匹配字串開始 |
| \Z | 匹配字串結束,如果是存在換行,只匹配到換行前的結束字串, |
| \z | 匹配字串結束 |
| \G | 匹配最后匹配完成的位置, |
| \b | 匹配一個單詞邊界,也就是指單詞和空格間的位置,例如, 'er\b' 可以匹配"never" 中的 'er',但不能匹配 "verb" 中的 'er', |
| \B | 匹配非單詞邊界,'er\B' 能匹配 "verb" 中的 'er',但不能匹配 "never" 中的 'er', |
| \n, \t, 等, | 匹配一個換行符,匹配一個制表符, 等 |
| \1...\9 | 匹配第n個分組的內容, |
| \10 | 匹配第n個分組的內容,如果它經匹配,否則指的是八進制字符碼的運算式, |
注意:表中re指的是運算式而不是字面的re這兩個字母
Python中正則運算式修飾符 - 可選標志
正則運算式可以包含一些可選標志修飾符來控制匹配的模式,修飾符被指定為一個可選的標志,多個標志可以通過按位 OR(|) 它們來指定,如 re.I | re.M 被設定成 I 和 M 標志:
| 修飾符 | 描述 |
|---|---|
| re.I | 使匹配對大小寫不敏感 |
| re.L | 做本地化識別(locale-aware)匹配 |
| re.M | 多行匹配,影響 ^ 和 $ |
| re.S | 使 . 匹配包括換行在內的所有字符 |
| re.U | 根據Unicode字符集決議字符,這個標志影響 \w, \W, \b, \B. |
| re.X | 該標志通過給予你更靈活的格式以便你將正則運算式寫得更易于理解, |
正則運算式物件
re.RegexObject
re.compile() 回傳 RegexObject 物件,
re.MatchObject
group() 回傳被 RE 匹配的字串, start()回傳匹配開始的位置 nd()回傳匹配結束的位置 span()回傳一個元組包含匹配 (開始,結束) 的位置
舉幾個栗子
匹配出河南省焦作市溫縣所有2000年后出生的人的身份證號
'^410825[^10]\d{3}\d{7}[0-9x]'
匹配出一篇檔案中所有的div.user-info標簽<div >username:Monkey</div>
'<div >.*</div>'
匹配出name和age
msg = 'name:monkey,age:100;'
obj = re.match('name:(\w+),age:(\d+)', msg)
print(obj.group(0)) # name:monkey,age:100 原始字符
print(obj.group(1)) # monkey 第一匹配
print(obj.group(2)) # 100
print(obj.groups()) # ('monkey', '100')
約束密碼中必須有除下劃線外的特殊字符
'.*\W+.*'
| rules | meaning |
|---|---|
| {n,m} | 來限制匹配的長度 |
| [abc] | 用來限制匹配的范圍 必須是 a或b或c |
| [^abc] | 不能是 a或b或c |
| | | 表示或 1(1|2)0可以匹配 110 或 120 |
| ^表示行的開頭 | ^\d表示必須以數字開頭, |
| $表示行的結束 | \d$表示必須以數字結束, |
re模常用方法
re.match()
re.match 嘗試從字串的起始位置匹配一個模式,如果不是起始位置匹配成功的話,match()就回傳none,
語法
re.match(pattern, string, flags=0)
"""
pattern : 匹配的正則運算式
string : 要匹配的字串
flags : 標志位,用于控制正則運算式的匹配方式,如:是否區分大小寫,多行匹配等等,參見上方可選標志表格
"""
例子
print(re.match('Monkey', 'Monkey is a good boy!').span())
print(re.match('goood boy', 'Monkey is a good boy!'))
# __________________________
# (0, 6)
# None
re.search()
re.search 掃描整個字串并回傳第一個成功的匹配,
語法
re.search(pattern, string, flags=0)
import re
re.search(pattern, string, flags=0)
"""
pattern : 匹配的正則運算式
string : 要匹配的字串
flags : 標志位,用于控制正則運算式的匹配方式,如:是否區分大小寫,多行匹配等等,參見上方可選標志表格
"""
例子
import re
x = re.search('monkey','monkey, monkey, _kali monkey')
print(x.span())
# (0, 6)
re.compile()
compile 函式用于編譯正則運算式,生成一個正則運算式( Pattern )物件,
提前編譯可減少多次正則匹配的運行時間
語法
import re
re.compile(pattern, flags=0)
"""
pattern : 匹配的正則運算式
flags : 可選標志位,用于控制正則運算式的匹配方式,如:是否區分大小寫,多行匹配等等,參見上方可選標志表格
"""
例子
import re
msg =re.compile('<div >(.*)</div>')
ret = msg.findall('<div >商品資訊</div>')
print(ret)
# ['商品資訊']
re.findall()
在字串中找到正則運算式所匹配的所有子串,并回傳一個串列,如果沒有找到匹配的,則回傳空串列,
match 和 search 是匹配一次 findall 匹配所有,
語法
re.findall(pattern, string, flags=0)
"""
pattern : 匹配的正則運算式
string : 要匹配的字串
flags : 標志位,用于控制正則運算式的匹配方式,如:是否區分大小寫,多行匹配等等,參見上方可選標志表格
"""
實體
import re
ret = re.findall('my', 'my name is monkey,my phone number is xxxx')
# ['my', 'my']
re.finditer()
和 findall 類似,findall() 匹配字串中的所有結果回傳串列,finditer()回傳一個迭代器,
語法
re.finditer(pattern, string, flags=0)
"""
pattern : 匹配的正則運算式
string : 要匹配的字串
flags : 標志位,用于控制正則運算式的匹配方式,如:是否區分大小寫,多行匹配等等,參見上方可選標志表格
"""
實體
import re
ret = re.findall('my', 'my name is monkey,my phone number is xxxx')
# <callable_iterator object at 0x109852518>
re.split()
split 方法按照能夠匹配的子串將字串分割后回傳串列,它的使用形式如下
語法
re.split(pattern, string[, maxsplit=0, flags=0])
"""
"""
實體
import re
ret = re.split(',+', 'name:monkey,gender:male,addr:xxxxx,,,,hobby:lady')
print(ret)
# ['name:monkey', 'gender:male', 'addr:xxxxx', 'hobby:lady']
re.sub()
Python 的re模塊提供了re.sub用于替換字串中的匹配項,
語法
re.sub(pattern, repl, string, count=0, flags=0)
"""
pattern : 必填 模式字串,
repl : 必填 替換的字串物件,也可為一個函式物件,
string : 必填 要被查找替換的原始字串,
count : 模式匹配后替換的最大次數,默認 0 表示替換所有的匹配,
flags : 編譯時用的匹配模式,數字形式 預設為 0
"""
前三個為必選引數,后兩個為可選引數,
實體
# 將所有年齡改成18歲
msg = 'name:monkey,age:100;' \
'name:hook,age:80;' \
'name:black,age:90;'
r = re.sub(':\d+;', ':18;', msg, count=0)
# name:monkey,age:18;name:hook,age:18;name:black,age:18;
分組與命名
分組
以括號()包裹起來,叫一個分組,分組是可以嵌套的
msg = 'name:monkey,age:100;'
r = re.match('name:(\w+),age:(\d+)', msg)
print(r.groups())
# ('monkey', '100')
命名
Django 1.x 版本的URLconf 中使用命名匹配來提取URL引數
msg = 'name:monkey,age:100;'
r = re.match('name:(?P<name>\w+),age:(?P<age>\d+)', msg)
print(r.groupdict())
# {'name': 'monkey', 'age': '100'}
貪婪匹配
re.match(r'^(\d+)(0*)$', '102300').groups()
('102300', '')
正則默認是貪婪的,也就是說會盡可能多的去匹配字符,
由于\d+采用貪婪匹配,直接把后面的0全部匹配了,結果0*只能匹配空字串了,
如果希望分開匹配,那必須讓\d+采用非貪婪匹配(也就是盡可能少匹配),才能把后面的0匹配出來,加個?就可以讓\d+采用非貪婪匹配:
re.match(r'^(\d+)(0*)$', '102300').groups()
('1023', '00')
正則運算式一些實體 字符匹配
| re | meaning |
|---|---|
| python | 匹配 "python" |
| [Pp]ython | 匹配 "Python" 或 "python" |
| rub[ye] | 匹配 "ruby" 或 "rube" |
| [aeiou] | 匹配中括號內的任意一個字母 |
| [0-9] | 匹配任何數字,類似于 [0123456789] [a-z] 匹配任何小寫字母 |
| [A-Z] | 匹配任何大寫字母 |
| [a-zA-Z0-9] | 匹配任何字母及數字 |
| [^aeiou] | 除了aeiou字母以外的所有字符 |
| [^0-9] | 匹配除了數字外的字符 |
特殊字符類
| re | meaning |
|---|---|
| . | 匹配除 "\n" 之外的任何單個字符,要匹配包括 '\n' 在內的任何字符,請使用象 '[.\n]' 的模式, |
| \d | 匹配一個數字字符,等價于 [0-9], |
| \D | 匹配一個非數字字符,等價于 [^0-9], |
| \s | 匹配任何空白字符,包括空格、制表符、換頁符等等,等價于 [ \f\n\r\t\v], |
| \S | 匹配任何非空白字符,等價于 [^ \f\n\r\t\v], |
| \w | 匹配包括下劃線的任何單詞字符,等價于'[A-Za-z0-9_]', |
| \W | 匹配任何非單詞字符,等價于 '[^A-Za-z0-9_]', |
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/117819.html
標籤:Python
上一篇:動態的為 物件系結方法
