正則表達(dá)式概述
什么是正則表達(dá)式
????正則表達(dá)式:(Regular Expression)竿拆,是一些有特殊的字符和符號組成的字符串挑辆,主要用來進(jìn)行高級的文本搜索、匹配魔慷、替代等功能只锭。
第一個(gè)正則表達(dá)式
????通過定義一個(gè)簡單的正則表達(dá)式,然后在目標(biāo)字符串中進(jìn)行查詢匹配的操作院尔,完成第一個(gè)程序的編寫蜻展,同時(shí)對于正則表達(dá)式又一個(gè)初步的了解和認(rèn)知。
# 引入正則表達(dá)式模塊
import re
# 目標(biāo)字符串
s = 'food foo tonight'
# 正則表達(dá)式
r = r'foo'
# 在目標(biāo)字符串中查詢符合正則表達(dá)式的字符
res = re.findall(r, s)
# 打印結(jié)果 查詢到兩個(gè)數(shù)據(jù)# ['foo', 'foo']
print(res)
Syntax of Regex(正則表達(dá)式操作語法)
Base Syntax
????正則表達(dá)式的核心就是匹配邀摆,匹配用到的也是字符串纵顾,對于正則表達(dá)式的理解就需要對正則表達(dá)式的語法有一個(gè)比較良好的熟悉度。下面針對正則表達(dá)式的常見操作栋盹,分成三個(gè)部分進(jìn)行了簡要描述施逾,對正則表達(dá)式語法先有一個(gè)全面的了解。
基本正則語法
符號 | 描述 |
---|---|
literal | 匹配文本字面值 |
re1|re2 | 匹配文本字符re1或re2 |
^ | 匹配目標(biāo)字符開頭位置 |
$ | 匹配目標(biāo)字符結(jié)束位置 |
. | 匹配任意一個(gè)字符(\n除外) |
? | 匹配任意一個(gè)字符出現(xiàn)0次或1次 |
+ | 匹配任意一個(gè)字符出現(xiàn)1次或n次 |
* | 匹配任意一個(gè)字符出現(xiàn)0次或n次 |
{m} | 匹配任意一個(gè)字符出現(xiàn)m次 |
{m,} | 匹配任意一個(gè)字符至少出現(xiàn)m次 |
{,n} | 匹配任意一個(gè)字符最多出現(xiàn)n次 |
{m,n} | 匹配任意一個(gè)至少出現(xiàn)m次例获,最多出現(xiàn)n次 |
[0-9] | 匹配任意一個(gè)0-9之間的數(shù)字 |
[^0-9] | 匹配任意一個(gè)非數(shù)字字符 |
[3-6] | 匹配任意一個(gè)3-6之間的數(shù)字 |
[0-10] | 匹配00或10兩個(gè)數(shù)字 |
[a-z] | 匹配任意一個(gè)小寫字母 |
[A-Z] | 匹配任意一個(gè)大寫字符 |
[a-zA-Z] | 匹配任意一個(gè)字母 |
[a-zA-Z0-9_] | 匹配任意一個(gè)字母/數(shù)字/下劃線 |
(..) | 匹配分組表達(dá)式 |
# coding:utf-8
import re
target = '''Are you new to Django or to programming? This is the place to start!
From scratch: Overview | Installation
Tutorial: Part 1: Requests and responses | Part 2: Models and the admin site
| Part 3:
Views and templates | Part 4: Forms and generic views | Part 5: Testing |
Part 6:
Static files | Part 7: Customizing the admin site
Advanced Tutorials: How to write reusable apps | Writing your first patch
for Django
'''
# 基本語法:字符匹配
reg1 = r"to"
print(re.findall(reg1, target))
# ['to', 'to', 'to', 'to', 'to', 'to', 'to']
# 基本語法:或者匹配
reg2 = r"Django|Part"
print(re.findall(reg2, target))
# ['Django', 'Part', 'Part', 'Part', 'Part', 'Part', 'Part', 'Part', 'Django']
# 基本語法:開頭匹配
reg3 = r"^Are"
print(re.findall(reg3, target))
# ['Are']
# 基本語法:結(jié)尾匹配
reg4 = r"Django$"
print(re.findall(reg4, target))
# ['Django']
# 基本語法:任意字符匹配
reg5 = r"Ho."
print(re.findall(reg5, target))
# ['How']
# 基本語法:范圍匹配?汉额,匹配一個(gè)字符出現(xiàn)了0次或1次
reg6 = r"pr?"
print(re.findall(reg6, target))
# ['pr', 'p', 'p', 'p', 'p', 'p', 'p']
# 基本語法:范圍匹配+,匹配一個(gè)字符出現(xiàn)了1次或n次
reg7 = r"pr+"
print(re.findall(reg7, target))
# ['pr']
# 基本語法:范圍匹配*榨汤,匹配一個(gè)字符出現(xiàn)了0次或n次
reg8 = r"pr*"
print(re.findall(reg8, target))
# ['pr', 'p', 'p', 'p', 'p', 'p', 'p']
# 基本語法:范圍匹配{m}蠕搜,匹配一個(gè)字符出現(xiàn)了m次
"""
范圍匹配:
{m,n}:匹配一個(gè)字符至少出現(xiàn)m次,至多出現(xiàn)n此
{m,}:匹配一個(gè)字符至少出現(xiàn)m次收壕,至多不限
{,n}:匹配一個(gè)字符至多出現(xiàn)n次妓灌,至少不限
"""
reg9 = r"l{2}"
print(re.findall(reg9, target))
# ['ll']
# 基本語法:范圍匹配[0-9],匹配出現(xiàn)了一個(gè)0-9之間的數(shù)字
reg10 = r"[0-9]+"
print(re.findall(reg10, target))
# ['1', '2', '3', '4', '5', '6', '7']
# 基本語法:范圍匹配[a-z]([A-Z])啼器,匹配出現(xiàn)了一個(gè)a-z(A-Z)之間的小寫(大寫)字母
reg11 = r"[a-z]{10}"
print(re.findall(reg11, target))
# ['programmin', 'nstallatio', 'ustomizing']
# 基本語法:范圍匹配[a-zA-Z0-9_]旬渠,匹配一個(gè)字母、數(shù)字或下劃線
reg12 = r"[a-zA-Z0-9_]{10}"
print(re.findall(reg12, target))
# ['programmin', 'Installati', 'Customizin']
分組查詢
# coding:utf-8
import re
target = '''
<img src="./images/1.jpg"/>
<img src="./images/2.jpg"/>
<img src="./images/3.jpg"/>
<img src="./images/4.jpg"/>
<img src="./images/5.jpg"/>'''
# 正則表達(dá)式中添加分組語法
reg = r'<img\s+src="(.*)"/>'
res = re.finditer(reg, target)
for r in res:
# print(r.group())
print(r.group(1))
正則表達(dá)式:元字符
符號 | 描述 |
---|---|
\d | 匹配任意一個(gè)[0-9]的數(shù)字 |
\D | 匹配任意一個(gè)非數(shù)字字符 |
\s | 匹配任意一個(gè)空白字符(\n\t\r\v\f) |
\S | 匹配任意一個(gè)非空白字符 |
\w | 匹配任意一個(gè)字母/數(shù)字/下劃線 |
\W匹配任意一個(gè)非字母/數(shù)字/下劃線 | |
\b | 匹配任意一個(gè)單詞的邊界 |
轉(zhuǎn)義字符端壳,可以用于匹配正則中用到的字符 |
# coding:utf-8
import re
# 目標(biāo)字符串
target = """Django community 11445 people, 164 countries, 3845 packages and projects."""
# 元字符:\d告丢,匹配任意一個(gè)[0-9]的數(shù)字
reg1 = r"\d+"
print(re.findall(reg1, target))
# ['11445', '164', '3845']
# 元字符:\s,匹配任意一個(gè)空白字符
reg2 = r"\s+"
print(re.findall(reg2, target))
# [' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ']
# 元字符:\b损谦,匹配任意一個(gè)數(shù)字/字母/下劃線
reg3 = r"\w{5}"
print(re.findall(reg3, target))
# ['Djang', 'commu', '11445', 'peopl', 'count', 'packa', 'proje']
# 元字符:岖免,匹配任意一個(gè)單詞的邊界
reg4 = r"\ban."
print(re.findall(reg4, target))
# ['and']
正則表達(dá)式:零寬斷言
符號 | 描述 |
---|---|
(?reg) | 特殊標(biāo)記參數(shù) |
(?:reg) | 匹配不用保存的分組 |
(?P<name>reg) | 匹配到分組結(jié)果命名為name |
(?P=name) | 注釋(?P<name>reg)前的文本 |
(?#content) | 注釋 |
(?=reg) | 正向前視斷言 |
(?!reg) | 負(fù)向前視斷言 |
(?<=reg) | 正向后視斷言 |
(?<!reg) | 負(fù)向后視斷言 |
(?(id/name)Yre1/Nre2) | 條件斷言分組 |
# coding:utf-8
import re
# 目標(biāo)字符串
target = 'aahelloworldbbhellojerryjerryup'
# 零寬斷言:正向前視斷言
reg1 = r'.{2}hello(?=world)'
res = re.finditer(reg1, target)
for r in res:
print(r.group()) # aahello
reg2 = r'.{2}hello(?!world)'
res = re.finditer(reg2, target)
for r in res:
print(r.group()) # bbhello
reg3 = r'(?<=hello)jerry.{2}'
res = re.finditer(reg3, target)
for r in res:
print(r.group()) # jerryje
reg4 = r'(?<!hello)jerry.{2}'
res = re.finditer(reg4, target)
for r in res:
print(r.group()) # jerryup
貪婪匹配 & 懶惰匹配
????貪婪模式和懶惰模式(非貪婪模式)是在正則操作過程中,需要嚴(yán)格注意的一個(gè)問題照捡,如果操作不當(dāng)?shù)脑捄苋菀自谄ヅ溥^程中得到非正常數(shù)據(jù)或者垃圾數(shù)據(jù)颅湘。
什么是貪婪和非貪婪模式
貪婪模式:在正則表達(dá)式匹配成功的前提下,盡可能多的匹配結(jié)果數(shù)據(jù)
非貪婪模式:在正則表達(dá)式匹配成功的前提下栗精,盡可能少的匹配結(jié)果數(shù)據(jù)
貪婪和非貪婪模式
# coding:utf-8
import re
target = "<div>hello</div><p>world</p><div>regular expression</div>"
# 正則表達(dá)式:貪婪匹配
reg = re.compile(r"<div>.*</div>")
# 查詢數(shù)據(jù)
res = reg.search(target)
print(res.group())
# <div>hello</div><p>world</p><div>regular expression</div>
# 正則表達(dá)式:懶惰匹配(非貪婪匹配)
reg = re.compile(r"<div>.*?</div>")
# 查詢數(shù)據(jù)
res = reg.search(target)
print(res.group())
# <div>hello</div>
pyhton中的正則
re正則模塊
python中通過標(biāo)準(zhǔn)庫re模塊對于正則表達(dá)式進(jìn)行良好的技術(shù)支持闯参。
為什么使用正則表達(dá)式
????正則表達(dá)式本身就是對于字符串的高效處理瞻鹏,盡管字符串本身也內(nèi)置了一些操作函數(shù),但是相對于較為復(fù)雜的需求鹿寨,通過正則表達(dá)式的操作更加靈活并且效率更高新博。
????正則表達(dá)式在程序中的主要應(yīng)用,有以下幾個(gè)方面:
????????匹配:測試一個(gè)字符串是否符合正則表達(dá)式語法脚草,返回 True 或者 False
????????獲群涨摹:從目標(biāo)字符串中,提取符合正則表達(dá)式語法的字符數(shù)據(jù)
????????替換:在目標(biāo)字符串中查詢符合正則語法的字符馏慨,并替換成指定的字符串
????????分割:按照符合正則表達(dá)式的語法字符對目標(biāo)字符串進(jìn)行分割
創(chuàng)建正則表達(dá)式的方式
????python中有兩種方式可以創(chuàng)建正則表達(dá)式的匹配對象埂淮,兩種方式使用都較為廣泛,具體滿足開發(fā)人員所在的團(tuán)隊(duì)的開發(fā)規(guī)范即可写隶。
隱式創(chuàng)建:通過一個(gè)普通字符串倔撞,直接創(chuàng)建正則表達(dá)式
要求:必須通過re模塊的函數(shù)調(diào)用才能正常編譯執(zhí)行
import re
# 創(chuàng)建一個(gè)正則表達(dá)式
reg = r"\bfoo\b"
# 從目標(biāo)字符串中提取數(shù)據(jù)
result = re.findall(reg, target_str)
顯式創(chuàng)建:通過內(nèi)建函數(shù)compile()編譯創(chuàng)建一個(gè)正則表達(dá)式對象
要求:可以通過調(diào)用該類型的方法,完成字符串的操作
import re
pattern = re.compile("\\bfoo\\b")
pattern.findall(target_str)
簡要操作案例
# coding:utf-8
import re
target = "helloworldhelloregexp"
# 1.函數(shù)
reg1 = r"(?<=hello).{3}"
print(re.findall(reg1, target))
# ['wor', 'reg']
# 2.對象
reg2 = re.compile(r"(?<=hello).{3}")
print(reg2.findall(target))
# ['wor', 'reg']
re模塊常用方法
常用方法
常用方法 | 描述 |
---|---|
re.findall(s, start, end) | 返回(指定位置)查詢到結(jié)果內(nèi)容的列表 |
re.finditer(s, start, end) | 返回(指定位置)查詢到結(jié)果匹配對象的生成器 |
re.search(s, start, end) | 返回(指定位置)第一次查詢到的匹配對象 |
re.match(s, start, end) | 返回(指定位置)從第一個(gè)字符匹配到的結(jié)果 |
re.sub(s, r, c) | 使用r替換字符串中所有匹配的數(shù)據(jù)樟澜,c是替換次數(shù) |
re.subn(s, r, c) | 使用r替換字符串中所有匹配的數(shù)據(jù)误窖,c是替換次數(shù) |
re.split(s, m) | 使用正則表達(dá)式拆分字符串,m是拆分次數(shù) |
簡單示例
# coding:utf-8
import re
target = "helloworldhellojerryhelloregularexpression"
# 定義正則表達(dá)式
reg = r"hello"
# findall()
print(re.findall(reg, target))
# ['hello', 'hello', 'hello']
# finditer()
res = re.finditer(reg, target)
for r in res:
print(r.group())
# hello
# hello
# hello
# search()
res = re.search(reg, target)
print(res)
# <_sre.SRE_Match object; span=(0, 5), match='hello'>
# match()
res = re.match(reg, target)
print(res)
# <_sre.SRE_Match object; span=(0, 5), match='hello'>
# sub()
res = re.sub(reg, "**", target)
print(res)
# **world**jerry**regularexpression
# subn()
res = re.subn(reg, "**", target)
print(res)
# ('**world**jerry**regularexpression', 3)
# split()
res = re.split(reg, target)
print(res)
# ['', 'world', 'jerry', 'regularexpression']