日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > python >内容正文

python

Python的正则表达式和re模块

發(fā)布時(shí)間:2024/3/13 python 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Python的正则表达式和re模块 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

1. 正則表達(dá)式

1.1 用處

正則表達(dá)式就是記錄文本規(guī)則的代碼

這句話我覺(jué)得概括的很精煉.

1.2 元字符

正則表達(dá)式里有一些元字符, 他們代表的是很多意思, 有某種特征的集合呀, 不包括某種字符的集合呀.

1.2.1 匹配字符種類的元字符

以下探討的都是代表一個(gè)字符的元字符.

. : 就是英文字符的句號(hào) . , 匹配除了換行符以外的任意字符。

\s: 匹配任意的空白符,包括空格,制表符(Tab),換行符,中文全角空格等.
\S: 匹配任意不是空白符的字符.

\w: 匹配字母[a-z], [A-Z] 或數(shù)字[0-9] 或下劃線_ 或漢字等.
\W: 匹配任意不是字母,數(shù)字,下劃線,漢字的字符.

\d: 是匹配一位數(shù)字從0到9, 任意一個(gè)數(shù)字就行。
\D: 匹配任意非數(shù)字的字符

\b: 并不匹配這些單詞分隔字符中的任何一個(gè),它只匹配一個(gè)位置. 這個(gè)位置和后一個(gè)字符或者前一個(gè)字符的類型不一樣.
比如: \b\w, 這個(gè)\b就是匹配不是\w的字符, 并且不會(huì)匹配到這個(gè)字符; 如果是\b. , 就是匹配不是. 的字符. 就近匹配,比如\bAB 匹配A,AB\b 匹配B
\B: 就是上面反過(guò)來(lái), 說(shuō)不清, 舉例來(lái)看: ‘a(chǎn)abbc’ 中 ‘\Ba’ 匹配的是第二個(gè)a, 因?yàn)閈B代表跟后面的字符類型一樣的字符, 但是不要這個(gè)\B代表的字符.

[ ]:從中挑一個(gè)字符, 注意是一個(gè)字符, 例如[fuck]就是從f, u, c, k 四個(gè)字符中挑選一個(gè), 還有[0-9]從0到9選一個(gè), 還有[a-d]或者[E-G], 從a, b, c, d 或者E, F, G中選一個(gè).

| : 從前或者后, 選出取個(gè)來(lái), 是或的意思. 例如: ‘a(chǎn)bc|de’ 的符合匹配對(duì)象是’abc’ 或者’de’, 而不是’abc’ 或’abde’. 一定要注意.

[^ ]: 取反^配合[ ]使用, 就是[ ]內(nèi)的字符以外的字符都可以, 例如: [^\d]匹配除了數(shù)字以外的任意字符, [^aeiou]匹配除了aeiou這幾個(gè)字母以外的任意字符.

\A: 代表后面這個(gè)字符必須在字符串開(kāi)頭. 例如: ‘a(chǎn)ba’ 用’\Aa’ 來(lái)匹配, 能匹配到第一個(gè)a, 不能匹配到第二個(gè)a; 如果用’\Ab’ 來(lái)匹配, 匹配不到.

^: 用來(lái)表示, ^后面這個(gè)字符, 必須是一行的開(kāi)始, mutilline模式下, 會(huì)按行分隔符分隔成很多行, 所以會(huì)有很多行首, 在默認(rèn)模式和singleline模式下, 就是一個(gè)長(zhǎng)的字符串, 所以只有一個(gè)行首

$: $前面的這個(gè)字符, 必須是行尾, 規(guī)律同上.

一共11種.

1.2.2 控制字符數(shù)量的元字符

配合上面代表字符種類的元字符使用, 接在字符的后面, 可以代表字符重復(fù)多少次. 注意, 他們只控制前面一個(gè)字符的數(shù)量.

貪婪地匹配:
因?yàn)槟芷ヅ涞降臄?shù)量不確定, 所以就盡可能多的匹配, 比如’@bbb@bbb@’ 中, 用’@.+@’來(lái)匹配, 結(jié)果是’@bbb@bbb@’ .

* :前邊的內(nèi)容可以連續(xù)重復(fù)使用任意次以使整個(gè)表達(dá)式得到匹配。.* 連在一起, 在singleline模式下就意味著任意數(shù)量的不包含換行的字符。

+: 重復(fù)一次以上

?: 重復(fù)零次或一次

{n}: 重復(fù)n次

{n,}: 重復(fù)n次或更多次, {1,} 相當(dāng)于+ .

{n,m}: 重復(fù)n到m次, {0,1} 相當(dāng)于? . 例如: 0\d{2}-\d{8}。這里\d后面的{2}({8})的意思是前面\d必須連續(xù)重復(fù)匹配2次(8次), 用于匹配0xx-xxxxxxxx這樣的字符串.

有時(shí)候, 我們需要這些元字符的本意, 比如我就想查找?, 這是需要用\來(lái)取消這些字符的特殊意義, \?就表示?。所以要查找\本身,要用\.

正則表達(dá)式里的分枝條件指的是有幾種規(guī)則,只要滿足這些規(guī)則中的任意一種,都會(huì)被當(dāng)成匹配,因此我們要使用 | 把這些規(guī)則分開(kāi)。

懶惰地匹配:

還是上面那個(gè)例子, 如果只想要’@bbb@bbb@’ 中, 符合條件的第一個(gè)字符串, 就可以用’@.+?@’來(lái)匹配, 結(jié)果是’@bbb@’, 是左邊的那個(gè) .

*?: 重復(fù)任意次,但盡可能少重復(fù)
+?: 重復(fù)1次或更多次,但盡可能少重復(fù)
??: 重復(fù)0次或1次,但盡可能少重復(fù)
{n,m}?: 重復(fù)n到m次,但盡可能少重復(fù)
{n,}?: 重復(fù)n次以上,但盡可能少重復(fù)

1.2.3 匹配重復(fù)出現(xiàn)某一組成部分的字符串

有的時(shí)候, 我們要用到前面匹配的字符串, 但是我們是在寫(xiě)正則表達(dá)式, 不知道會(huì)匹配到什么, 可以用分組來(lái)解決.

(exp): 匹配exp, 并捕獲文本到自動(dòng)命名的組里. 然后用這些組的編號(hào)來(lái)調(diào)用, 最左邊定的分組編號(hào)是1, 以此類推. 例如’(\w).*?\1’ 可以匹配, ‘a(chǎn)fuckafuckf’ 中的’afucka’ 和’fuckf’ 這樣的字符串, 注意, 因?yàn)檫€沒(méi)有匹配, 所以分組捕獲的實(shí)際字符串是什么沒(méi)有確定, 只有開(kāi)始具體的字符串后, 才能知道分組匹配的是什么.

(?<>exp): 匹配exp, 在<>里面可以寫(xiě)分組的名字,但是調(diào)用分組的時(shí)候還是要寫(xiě)編號(hào), 估計(jì)這個(gè)分組只是一個(gè)注釋作用吧, 也可以寫(xiě)成(?’name’exp). 此處要吐槽CSDN這格式是個(gè)什么玩意.

(?:exp): 有時(shí)候要用()來(lái)改變匹配的優(yōu)先級(jí), 就要寫(xiě)成(?:)不然優(yōu)先級(jí)是改變了, 但是把不想分組的內(nèi)容分了組, 給了編號(hào), 可能會(huì)有不便.

分組0對(duì)應(yīng)整個(gè)正則表達(dá)式.

實(shí)際上組號(hào)分配過(guò)程是要從左向右掃描兩遍的:第一遍只給未命名組分配,第二遍只給命名組分配, 因此所有命名組的組號(hào)都大于未命名的組.

零寬斷言

斷言用來(lái)聲明一個(gè)應(yīng)該為真的事實(shí)。正則表達(dá)式中只有當(dāng)斷言為真時(shí)才會(huì)繼續(xù)進(jìn)行匹配。

正向:

(?=exp): 匹配以exp結(jié)尾的字符串, 不包快這個(gè)exp, 例如’\w(?=\d)’ 代表一個(gè)\w字符, 這個(gè)字符必須以數(shù)字結(jié)尾, 如果用來(lái)匹配’1a2bcde’, 匹配到的是a.

(?<=exp): 匹配以exp開(kāi)頭的字符串. 上面的例子:’(?<=\d)\w’ 匹配到的是a和b

負(fù)向:
(?!exp): 匹配不能以exp結(jié)尾的字符串.

(?<!exp): 匹配不能以exp開(kāi)頭的字符串.

注釋
(?#comment) 這種類型的分組不對(duì)正則表達(dá)式的處理產(chǎn)生任何影響,用于提供注釋讓人閱讀

1.3 一般的軟件模式

這些模式用于不同的需求. 以RegExTexter.exe為例, 默認(rèn)模式, 就是. 不能代表?yè)Q行符的單行模式.

IgnoreCase(忽略大小寫(xiě))模式:
匹配時(shí)不區(qū)分大小寫(xiě)。

Multiline(多行模式):
根據(jù)換行符, 把文本換行, 但是不去掉換行符.
主要作用就是, 變出了很多個(gè)行首和行尾.

Singleline(單行模式)
更改.的含義,使它與每一個(gè)字符匹配(包括換行符\n)。

2. re模塊

python中有適用于正則表達(dá)式的模塊, 就是re模塊.

在python中有兩種使用正則表達(dá)式的方法, 第一種是, 用re下的方法直接匹配, 但是需要以字符串的形式輸入正則表達(dá)式; 第二種是, 把正則表達(dá)式生成一個(gè)regex對(duì)象, 然后調(diào)用這個(gè)對(duì)象的方法來(lái)匹配.

匹配的返回值可以是str或者是match對(duì)象, match對(duì)象里面包含了匹配到的字符串的內(nèi)容和索引.

python也提供了幾種不同的模式來(lái)匹配:

re.I
re.IGNORECASE #這個(gè)模式是忽略字母的大小寫(xiě)

re.M
re.MULTILINE #多行模式

re.S
re.DOTALL #這個(gè)模式下, .也可以代表?yè)Q行符

re.X
re.VERBOSE #忽略大小寫(xiě)模式, 可以讓正則表達(dá)式看起來(lái)更好看, 我覺(jué)得還是別用吧

2.1 直接匹配:

re.match(pattern, string, flags=0)
pattern是正則表達(dá)式, string是要匹配的文本, flags是選擇用什么模式來(lái)匹配.

就是錨定開(kāi)頭, 這個(gè)正則表達(dá)式, 如果不再開(kāi)頭的話, 就算沒(méi)找到

匹配到了, 返回match對(duì)象. 沒(méi)匹配到, 什么都不返回.

import re a = re.match('\d', '123r123')print(a) (<_sre.SRE_Match object; span=(0, 1), match='1'>)

re.search(pattern, string, flags=0)
同樣值匹配一次, 但是沒(méi)有錨定開(kāi)頭

re.search('[^\d]', '123r123') <_sre.SRE_Match object; span=(3, 4), match='r'>

re.fullmatch(pattern, string, flags=0)
看整個(gè)字符串是否符合正則表達(dá)式

re.fullmatch('.*', 'r123rr123') <_sre.SRE_Match object; span=(0, 9), match='r123rr123'>

re.findall(pattern, string, flags=0)
從整個(gè)字符串開(kāi)始匹配, 找到結(jié)果, 把結(jié)果以列表的形式返回.

re.findall('[^\d]', '123r1a23') ['r', 'a']

re.finditer(pattern, string, flags=0)
也是從整個(gè)字符串里找
返回一個(gè)迭代器, 每次迭代出符合條件的match對(duì)象

a = re.finditer('[^\d]', '123r1a23') for i in a:print(i) <_sre.SRE_Match object; span=(3, 4), match='r'> <_sre.SRE_Match object; span=(5, 6), match='a'>

re.sub(pattern, repl, string, count=0, flags=0)
在string里找到符合pattern的字符串, 把它替換成repl,
count指定替換次數(shù), 默認(rèn)是0, 就是全局替換,
返回的是替換好的字符串.

re.sub('\d', 'fuck','1@a@3@b')'fuck@a@fuck@b'

re.subn(pattern, repl, string, count=0, flags=0)
跟上面那個(gè)用法一毛一樣, 區(qū)別就是, 這個(gè)會(huì)返回一個(gè)二元組, 第一個(gè)元素是替換好的string, 第二個(gè)元素是替換次數(shù).

re.subn('\d', 'fuck','1@a@-@b') ('fuck@a@-@b', 1)

(?<=<(\w+)>).*(?=<\/\1>)匹配不包含屬性的簡(jiǎn)單HTML標(biāo)簽內(nèi)里的內(nèi)容。

re.split(pattern, string, maxsplit=0, flags=0)
把string中符合pattern的字符串都切掉, 和str.split()效果差不多, maxsplit是指定切割次數(shù)的.

re.split('\d', 'ab1cd3efg4') ['ab', 'cd', 'efg', ''] #注意,如果string首尾符合pattern的話,會(huì)切出一個(gè)空串.很好解決#得到結(jié)果lst:list if lst[0] == '':lst.pop(0) if lst[-1] == '':lst.pop()

2.2 生成regex對(duì)象再匹配

re.compile(pattern, flags=0)
用標(biāo)識(shí)符來(lái)接收, 注意, 這個(gè)對(duì)象是要在匹配之前設(shè)置好匹配模式的.

a = re.compile('[fu][ck]', flags=re.I|re.M) print(a) print(type(a)) re.compile('[fu][ck]', re.IGNORECASE|re.MULTILINE) <class '_sre.SRE_Pattern'>

然后regex的方法和re的方法差不多, 后面只放目標(biāo)string就行了, 但是可以指定開(kāi)始和結(jié)束的位置:

regex.match(string[, pos[, endpos]])
regex.search(string[, pos[, endpos]])
regex.fullmatch(string[, pos[, endpos]])
regex.findall(string[, pos[, endpos]])
regex.finditer(string[, pos[, endpos]])
regex.sub(repl, string, count=0)
regex.subn(repl, string, count=0)
regex.split(string, maxsplit=0)

3. match對(duì)象

match.group([group1, …])
后面括號(hào)寫(xiě)分組的編號(hào), 可以得到字符串形式的分組

a = re.search('(\d)', 'ab1c') a.group(1) '1' #注意, 這個(gè)是out的, 不是print的

match.groups(default=None)
可以把所有的分組放在一個(gè)元組里面返回來(lái)

a = re.finditer('(\d)(\d)', '1a29bbb') for i in a :print(i.groups()) ('2', '9')

match.groupdict(default=None)
如果給分組命名了的話, 注意python中分組要用(?P<’name’>)來(lái)命名, 這個(gè)方法可以返回一個(gè)字典.

a = re.search('(?P<'fuck'>\d)(?P<'what'>\w)', 'ab1c2b3a') #其實(shí)名字可以不加單引號(hào), 但是CSDN太sb了不讓這么寫(xiě) print(type(a)) print(a.groupdict()) <class '_sre.SRE_Match'> {'fuck': '1', 'what': 'c'}

總結(jié)

以上是生活随笔為你收集整理的Python的正则表达式和re模块的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。