Python正則式初探

2021-09-01 19:53:29 字數 4436 閱讀 7234

先介紹下最常見的元字元metacharacter:

literal      匹配字串的值    foo

re1|re2   匹配正則式re1或re2    foo|bar

.              匹配乙個任何字元(換行符除外)  b.b

^              匹配字串開始           ^dear

$             匹配字串結束            /bin/*sh$

*              匹配前面出現的零次或多次      [a-za-z0-9]*

+             匹配前面出現的一次或多次       [a-z]+\.com

?             匹配前面出現的零次或一次       goo?

匹配前面出現的正則式n次         [0-9]

匹配前面出現的m次到n次         [0-9]

[...]          匹配字元組裡出現任意乙個字元        [aeiou]

[...x-y...]   匹配從字元x到y中的任意乙個字元     [a-za-z]

[^...]         匹配不在字符集中的任意乙個字元     [^a-za-z]

(*|+|?|{})? 用於上面出現的任何「非貪婪」版本重複匹配次數         .*?[a-z]

(...)          匹配封閉括號中的正則式,並儲存為子組         ([0-9])?

接下來再介紹幾個特殊字元:

\d            匹配任何乙個數字字元,和[0-9]一樣,\d是\d的反義詞,表示任何乙個非數字字元       data\d+\.txt

\w            匹配任何乙個數字字母下劃線字元,和[a-za-z0-9_]相同,\w跟\w相反      [a-za-z_]\w+

\s             匹配任何乙個空白符,和[\n\t\r\v\f ]相同, \s是\s的反義

\b             匹配單詞邊界,\b是\b的反義          \bthe\b

\nn           匹配已儲存的子組          price:\16

\c             逐一匹配特殊字元c,即取消它的特殊含義,按字面匹配    \.    \\,    \*

\a(\z)       匹配字串的起始(結束),跟^$是意義一樣

再用一張**釋全部:

這個方法是pattern類的工廠方法,用於將字串形式的正規表示式編譯為pattern物件。

第二個引數flag是匹配模式,取值可以使用按位或運算子'|'表示同時生效,比如re.i | re.m。

另外,你也可以在regex字串中指定模式,

比如re.compile('pattern', re.i | re.m)與re.compile('(?im)pattern')是等價的。

可選值有:

re.i(全拼:ignorecase): 忽略大小寫(括號內是完整寫法,下同)

re.m(全拼:multiline): 多行模式,改變'^'和'$'的行為(參見上圖)

re.s(全拼:dotall): 點任意匹配模式,改變'.'的行為

re.l(全拼:locale): 使預定字元類 \w \w \b \b \s \s 取決於當前區域設定

re.u(全拼:unicode): 使預定字元類 \w \w \b \b \s \s \d \d 取決於unicode定義的字元屬性

re.x(全拼:verbose): 詳細模式。這個模式下正規表示式可以是多行,忽略空白字元,並可以加入注釋。 

解釋下「非貪婪」匹配?

當表示重複次數的元字元(*+?)單獨使用時會盡量吸收更多的字元,一直吸到不匹配為止,榨**丫的。哈哈哈。

而上面的(*+?)後面接了?後,就表示非貪婪匹配,匹配最短的,留下盡可能多的字元給後面的模式(如果存在)。

使用compile()編譯正規表示式後,將正則式模式編譯成regex物件,以後重複使用這個物件的時候可以提公升執行的效能。

m = re.match('\w\w\w-\d\d\d', 'abc-123')

if m is not none:

print(m.group())

m = re.match('\w+\w+\w+-\d\d\d', 'abc-123')

if m is not none:

print(m.group())

m = re.match('\w+?\w+?\w+?-\d\d\d', 'abc-123')

if m is not none:

print(m.group())

哥原本以為那啥\w+會做貪婪匹配,弄的後面的兩個\w+沒得匹配,但是三個結果都一樣啊。神馬原因?

請看下面的:

m = re.match(r'(\w+)(\w+)(\w+)-\d\d\d', 'abcdefgh-123')

if m is not none:

print(m.group())

print(m.group(1))

print(m.group(2))

輸出:

abcdefgh-123

abcdef

g貪婪演算法是:我前面的盡可能多的匹配更多,但是我會保證後面的也能匹配的前提下,自己撈的越多越好,這個就跟**一樣,反正我給後面的那些平民百姓保本的東西,讓他們餓不死就行,自己撈的越多越好,真他嗎的黑心啊。

所以第一組中的(\w+)匹配了abcdef,留下兩個gh給後面去搶。每人分乙個,最小滿足後面的。

來來來,再看幾個例子:

import re

__author__ = 'xiong neng'

# group示例

data = 'thu'

patt1 = r'^(\w)'

m = re.match(patt1, data)

print(m.group(1))

patt2 = r'^(\w)'

m = re.match(patt2, data)

print(m.group(1))

# 貪婪匹配

data = "sat mar 21 09:20:57 2009::[email protected]::1237598457-6-9"

# 獲取最後的那三個連字元連起來的三個數,

# 搜尋比匹配更合適,因為不在開頭

patt = r'\d+-\d+-\d+'

print(re.search(patt, data).group()) # 列印出 1237598457-6-9

# 使用匹配,必須用到group

patt = r'.+(\d+-\d+-\d+)'

print(re.match(patt, data).group(1)) # 列印出 7-6-9,知道貪婪的厲害了吧。哈哈

# 接下來使用非貪婪操作符?

patt = r'.+?(\d+-\d+-\d+)'

print(re.match(patt, data).group(1)) # 列印出 1237598457-6-9

# 只獲取三個數的中間那個數字:

patt = r'-(\d+)-'

print(re.search(patt, data).group()) # 列印-6-

print(re.search(patt, data).group(1)) # 列印6

# 建議閱讀jeffrey e. f. friedl編寫的《精通正規表示式》(mastering regular expression)

最後是幾個小練習:

# 匹配所有整形字串

patt = r'\d+'

# 匹配長整形

patt = r'\d+[ll]'

# 匹配浮點型

patt = r'(-?(\d+\.\d*|\d*\.\d+))([ee]-?\d+)?'

print(re.match(patt, '-.2e-22').group())

print(re.match(patt, '23.23056e-23').group())

# 匹配所有複數

patt = r'(-?(\d+\.\d*|\d*\.\d+))([ee]-?\d+)?\s*[+-]\s*(\d+\.\d*|\d*\.\d+)([ee]-?\d+)?[jj]'

print(re.match(patt, '-.2e-22 - 32.e21j').group())

print(-.2e-22 - 32.e21j)

響應式實現初探

前段時間,因為專案需要,略微接觸了一下響應式設計。在此記錄一些經驗之談。我所理解的響應式設計,是 能響應當前螢幕的寬度,呈現相應合適的樣式和內容。比如在手機端,手機端螢幕較小,而且使用者可能在3g網路下訪問。在手機端下顯示的時候,呈現的內容較之桌面要少一些,所消耗的流量也要少些。通過css的 查詢,...

python 正則式使用心得

1.match 程式設計客棧 從開始位置開始匹配 2.sgqwepgearch 任意位置匹配,如果有多個匹配,只返回第乙個 3.finditer 返回所有匹配 程式設計客棧 4.每次匹配,都是盡量最大匹配。例如 m re.compile abc bcd b m.findall abcbcbcb ab...

C 函式式程式設計初探

一 什麼是函式式程式設計 函式式程式設計 fc 是以函式作為第一類值,避免狀態突變的程式設計風格。狀態突變 儲存在暫存器的值就地更新。二 c 中有哪些常見的函式式方法 linq的where和orderby函式對列表進行過濾或排序不會影響原始列表 sort函式對列表排序會影響原始列表。var nums...