Python 正規表示式

2022-04-22 20:51:24 字數 4064 閱讀 7598

1. re包常用函式

match(pattern, string, flags=0)

search(pattern, string, flags=0)

區別:match從頭開始匹配,若不符合則匹配失敗

search從整個string中進行匹配,直到找到乙個匹配

fullmatch(pattern, string, flags=0)

若string不是完全匹配則匹配失敗

sub(pattern, repl, string, count=0, flags=0)

用repl替換string中正規表示式匹配到的內容

split(pattern, string, maxsplit=0, flags=0)

compile(pattern, flags=0)

compile a regular expression pattern, returning a pattern object.

2. 正則字元介紹

普通字元

^: 匹配行或者字串的起始位置,有時還會匹配整個文件的起始位置

$: 匹配行或字串的結尾

\b: 不會消耗任何字元只匹配乙個位置,常用於匹配單詞邊界

·    如 我想從字串中"this is regex"匹配單獨的單詞 "is" 正則就要寫成 "\bis\b"

\d:匹配數字

\w:字母、數字、下劃線

\s:空格

重複

* 重複零次或更多次

+ 重複一次或更多次

?重複零次或一次

重複n次

重複n次或更多次

重複n到m次

字元類

[abcdefg] 匹配其中任意的乙個字元

[1-9] 匹配1-9範圍內的任意乙個數字

分支條件

| 表示分支條件

分組

()進行分組表示

反義

\w 匹配任意不是字母、數字、下劃線的字元

\s 匹配任意不是空白符的字元

\d 匹配任意非數字的字元

\b 匹配不是單詞開頭或結束的位置

[^x] 匹配除了x以外的任意字元

[^aeiou]匹配除了aeiou這幾個字母以外的任意字元

向後引用

分類**/語法

說明捕獲

(exp)

匹配exp,並捕獲文字到自動命名的組裡

(?exp)

匹配exp,並捕獲文字到名稱為name的組裡,也可以寫成(?'name'exp)

(?:exp)

匹配exp,不捕獲匹配的文字,也不給此分組分配組號

零寬斷言

(?=exp)

匹配exp前面的位置

(?<=exp)

匹配exp後面的位置

(?!exp)

匹配後面跟的不是exp的位置

(?匹配前面不是exp的位置

注釋(?#comment)

這種型別的分組不對正規表示式的處理產生任何影響,用於提供注釋讓人閱讀

零寬度斷言

接下來的四個用於查詢在某些內容(但並不包括這些內容)之前或之後的東西,也就是說它們像\b,^,$那樣用於指定乙個位置,這個位置應該滿足一定的條件(即斷言),

因此它們也被稱為零寬斷言。最好還是拿例子來說明吧:

斷言用來宣告乙個應該為真的事實。正規表示式中只有當斷言為真時才會繼續進行匹配。

(?=exp)也叫零寬度正**先行斷言,它斷言自身出現的位置的後面能匹配表示式exp。比如\b\w+(?=ing\b),匹配以ing結尾的單詞的前面部分(除了ing以外的部分),

如查詢i'

m singing while you

're dancing.時,它會匹配sing和danc。

(?<=exp)也叫零寬度正回顧後發斷言,它斷言自身出現的位置的前面能匹配表示式exp。比如(?<=\bre)\w+\b會匹配以re開頭的單詞的後半部分(除了re以外的部分),

例如在查詢reading a book時,它匹配ading。

假如你想要給乙個很長的數字中每三位間加乙個逗號(當然是從右邊加起了),你可以這樣查詢需要在前面和裡面新增逗號的部分:((?<=\d)\d)+\b,用它對1234567890進行查詢時結果是234567890。

下面這個例子同時使用了這兩種斷言:(?<=\s)\d+(?=\s)匹配以空白符間隔的數字(再次強調,不包括這些空白符)。

負向零寬度斷言

前面我們提到過怎麼查詢不是某個字元或不在某個字元類裡的字元的方法(反義)。但是如果我們只是想要確保某個字元沒有出現,但並不想去匹配它時怎麼辦?例如,

如果我們想查詢這樣的單詞--它裡面出現了字母q,但是q後面跟的不是字母u,我們可以嘗試這樣:

\b\w*q[^u]\w*\b匹配包含後面不是字母u的字母q的單詞。但是如果多做測試(或者你思維足夠敏銳,直接就觀察出來了),你會發現,如果q出現在單詞的結尾的話,

像iraq,benq,這個表示式就會出錯。這是因為[^u]總要匹配乙個字元,所以如果q是單詞的最後乙個字元的話,後面的[^u]將會匹配q後面的單詞分隔符(可能是空格,或者是句號或其它的什麼),

後面的\w*\b將會匹配下乙個單詞,於是\b\w*q[^u]\w*\b就能匹配整個iraq fighting。負向零寬斷言能解決這樣的問題,因為它只匹配乙個位置,並不消費任何字元。

現在,我們可以這樣來解決這個問題:\b\w*q(?!u)\w*\b。

零寬度負**先行斷言(?!exp),斷言此位置的後面不能匹配表示式exp。例如:\d(?!\d)匹配三位數字,而且這三位數字的後面不能是數字;

\b((?!abc)\w)+\b匹配不包含連續字串abc的單詞。

同理,我們可以用(?7

}匹配前面不是小寫字母的七位數字。

請詳細分析表示式(?<=<(\w+)>).*(?=<\/\1>),這個表示式最能表現零寬斷言的真正用途。

乙個更複雜的例子:(?<=<(\w+)>).*(?=<\/\1>)匹配不包含屬性的簡單html標籤內裡的內容。(?<=<(\w+)>)指定了這樣的字首:

被尖括號括起來的單詞(比如可能是),然後是.*(任意的字串),最後是乙個字尾(?=<\/\1>)。注意字尾裡的\/,它用到了前面提過的字元轉義;

\1則是乙個反向引用,引用的正是捕獲的第一組,前面的(\w+)匹配的內容,這樣如果字首實際上是的話,字尾就是了。

整個表示式匹配的是之間的內容(再次提醒,不包括字首和字尾本身)。

注:上述部分內容摘抄自部落格:

import

restring="

abcdefg acbdgef abcdgfe cadbgfe"#

帶括號與不帶括號的區別

#不帶括號

regex=re.compile("

((\w+)\s+\w+)")

print

(regex.findall(string))

#輸出:[('abcdefg acbdgef', 'abcdefg'), ('abcdgfe cadbgfe', 'abcdgfe')]

regex1=re.compile("

(\w+)\s+\w+")

print

(regex1.findall(string))

#輸出:['abcdefg', 'abcdgfe']

regex2=re.compile("

\w+\s+\w+")

print

(regex2.findall(string))

#輸出:['abcdefg acbdgef', 'abcdgfe cadbgfe']

python正規表示式元字元 正規表示式

字元 描述將下乙個字元標記為乙個特殊字元 或乙個原義字元 或乙個 向後引用 或乙個八進位制轉義符。例如,n 匹配字元 n n 匹配乙個換行符。序列 匹配 而 則匹配 匹配輸入字串的開始位置。如果設定了 regexp 物件的 multiline 屬性,也匹配 n 或 r 之後的位置。匹配輸入字串的結束...

Python 正規表示式

1.在python中,所有和正規表示式相關的功能都包含在re模組中。2.字元 表示 字串的末尾 如 road 則表示 只有當 road 出現在乙個字串的尾部時才會匹配。3.字元 表示 字元中的開始 如 road 則表示 只有當 road 出現在乙個字串的頭部時才會匹配。4.利用re.sub函式對字串...

Python正規表示式

學習python自然而然就不得不面對正規表示式這個難題。當初在沒有學習python之前,自己也曾經嘗試著學習過正規表示式,但是那時候感覺很麻煩,很難懂,結果就是不了了之。但是現在學習python我用的書是 python基礎教程 第二版 這本書中對re模組的講解很簡單易懂,內容不多但起碼把人領進門了,...