正則表達(dá)式

正則表達(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']
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末秩贰,一起剝皮案震驚了整個(gè)濱河市霹俺,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌毒费,老刑警劉巖丙唧,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異觅玻,居然都是意外死亡想际,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進(jìn)店門溪厘,熙熙樓的掌柜王于貴愁眉苦臉地迎上來胡本,“玉大人,你說我怎么就攤上這事畸悬〔喔Γ” “怎么了?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵蹋宦,是天一觀的道長披粟。 經(jīng)常有香客問我,道長冷冗,這世上最難降的妖魔是什么守屉? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮蒿辙,結(jié)果婚禮上拇泛,老公的妹妹穿的比我還像新娘滨巴。我一直安慰自己,他們只是感情好俺叭,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布兢卵。 她就那樣靜靜地躺著,像睡著了一般绪颖。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上甜奄,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天柠横,我揣著相機(jī)與錄音,去河邊找鬼课兄。 笑死牍氛,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的烟阐。 我是一名探鬼主播胚股,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼淀歇,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起谭胚,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎啡莉,沒想到半個(gè)月后靡馁,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡屿聋,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年空扎,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片润讥。...
    茶點(diǎn)故事閱讀 38,039評論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡转锈,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出楚殿,到底是詐尸還是另有隱情撮慨,我是刑警寧澤,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布勒魔,位于F島的核電站甫煞,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏冠绢。R本人自食惡果不足惜抚吠,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望弟胀。 院中可真熱鬧楷力,春花似錦喊式、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至检柬,卻和暖如春献联,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背何址。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工里逆, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人用爪。 一個(gè)月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓原押,卻偏偏與公主長得像,于是被迫代替她去往敵國和親偎血。 傳聞我的和親對象是個(gè)殘疾皇子诸衔,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評論 2 345

推薦閱讀更多精彩內(nèi)容