Python學習筆記 11章 正規表示式

2021-08-28 08:17:57 字數 4319 閱讀 4122

1、正則表

\d匹配乙個數字\w

匹配乙個字母或數字\s

可以匹配乙個空格(也包括tab等空白符)

.匹配任意乙個字元

*表示重複前面的乙個字元

0次或多次(包括

0個)例如:

ab* will match 『a』, 『ab』, 『

abbbbb...』?

表示0個或1

個字元表示n個字元

表示n-m個字元

\轉義字元,

\\ 表示對

\本身轉義

表範圍,如[0-9a-za-z]

如[a-za-z\_][0-9a-za-z\_]*:前面的

匹配開頭,後面的

* 匹配任意個字元

{}如[a-za-z\_][0-9a-za-z\_]:精確地限制了變數的長度是1-20個字元(前面1個字元+後面最多19個字元)

|表或,如a|b可以匹配a或b,(p|p)ython可以匹配'python'或者'python'

^匹配開頭

$匹配結尾

注意:py也可以匹配'python',但是加上^py$就變成了整行匹配,就只能匹配'py'了。類似於grep 和 grep -w的區別2、

re模組

python提供re模組,包含所有正規表示式的功能。下面做一些練習

1)普通寫法

>>> s = 'abc\\-001'

>>> print(s)

abc\-001

2)字首寫法

>>> s = r'abc\-001'# 用

r字首,不用考慮轉義的問題。類似於

shell

裡的egrep

,sed -r

>>> print(s)

abc\-001

3)判斷正規表示式是否匹配

>>> import re

# match()方法判斷是否匹配。匹配成功,返回match物件,匹配不成功,無顯示。這裡對-用了轉義符,不用也行

>>>

re.match

(r'^\d\-\d$', '010-12345')

<_sre.sre_match object; span=(0, 9), match='010-12345'>

4)match()方法的if 判斷

test = '使用者輸入的字串'

if re.match(r'正規表示式', test):

print('ok')

else:

print('failed')

5)用正則切分字串

>>> 'a b   c'.split(' ')

# 正常的**無法識別連續的空格

['a', 'b', '', '', 'c']

>>>

re.split

(r'\s+', 'a b   c')

# 正則可以

['a', 'b', 'c']

6)分組

除了簡單地判斷是否匹配之外,正規表示式還有提取子串的強大功能。用()表示的就是要提取的分組(group)

>>> m = re.match(r'^(\d)-(\d)$', '010-12345')

#()裡面的正則匹配的字元換就是乙個組

>>> m

<_sre.sre_match object; span=(0, 9), match='010-12345'>

>>> m.group(0)

# group(0)

,表示整個字串

'010-12345'

>>> m.group(1)

# 表示第一組字串

'010'

>>> m.group(2)

# 表示第二組字串

'12345'

>>> t = '19:05:30'

# 匹配時,分,秒。注意

()裡的

| >>> m = re.match(r'^(0[0-9]|1[0-9]|2[0-3]|[0-9])\:(0[0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9]|[0-9])\:(0[0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9]|[0-9])$', t)

>>> m.groups()

('19', '05', '30')

7)貪婪匹配

正則匹配預設是貪婪匹配,也就是匹配盡可能多的字元。

# (\d+)表示匹配多個數字,直接把數字匹配完了,沒有給(0*)$匹配的機會

>>> re.match(r'^(\d+)(0*)$', '102300').groups()

('102300', '')

8)非貪婪匹配

讓\d+採用非貪婪匹配(也就是盡可能少匹配),才能把後面的0匹配出來,加個?就可以讓\d+採用非貪婪匹配

#  ^(\d+?),盡可能少的匹配,給後面的(0*)$留下了匹配的空間

>>> re.match(r'^(\d+?)(0*)$', '102300').groups()

('1023', '00')

2.1、編譯

當我們在python中使用正規表示式時,re模組內部會幹兩件事情:

編譯正規表示式,如果正規表示式的字串本身不合法,會報錯;

用編譯後的正規表示式去匹配字串。

如果乙個正規表示式要重複使用幾千次,出於效率的考慮,我們可以預編譯該正規表示式,接下來重複使用時就不需要編譯這個步驟了,直接匹配:

>>> import re

# 編譯:

編譯出的物件是類

>>>

re_telephone =

re.compile

(r'^(\d)-(\d)$')

# 使用:使用了類的match()方法

# 編譯後生成regular expression物件,由於該物件自己包含了正規表示式,所以呼叫對應的方法時不用給出正則字串。

>>>

re_telephone.match

('010-12345').groups()

# 注意這個

groups()

,是顯示整個字串,前面用的是

group()

,group(1)

('010', '12345')

>>> re_telephone.match('010-8086').groups()

('010', '8086')

3、例題

1、寫乙個驗證

email

位址的正規表示式。版本一應該可以驗證出類似的

email:

# -*- coding: utf-8 -*-

import re

def is_valid_email(addr):

if re.match(r'^[a-za-z.]+@[a-za-z.]+$',addr):#不寫

^ 和$ 也沒影響

return true

else:

return false

# 測試:

assert is_valid_email('[email protected]')

assert is_valid_email('[email protected]')

assert not is_valid_email('bob#example.com')

assert not is_valid_email('[email protected]')

print('ok')

2、版本二可以提取出帶名字的

email

[email protected] => tom paris

[email protected] => bob

# -*- coding: utf-8 -*-

import re

def name_of_email(addr):

# <?([a-za-z\s]+)>?,可以把名字匹配出來,注意裡面的()。

# \s?[a-za-z]*?,對

tom而言,後面還需要匹配,而

bob不需要,所以用的是[a-za-z]*?,

* 表0個或多個字元。?讓

*別把後面的也匹配了

str = re.match(r'^<?([a-za-z\s]+)>?

\s?[a-za-z]*?(@[a-za-z.]+)$',addr)

return str.group(1)

# 測試:

assert name_of_email('[email protected]') == 'tom paris'

assert name_of_email('[email protected]') == 'tom'

print('ok')

Python 學習筆記(11)

1.arange arange 類似於python中的 range 函式,只不過返回的不是列表,而是陣列 arange start,stop none,step 1,dtype none 產生乙個在區間 start,stop 之間,以 step 為間隔的陣列,如果只輸入乙個引數,則預設從 0 開始,...

python學習筆記11(函式)

概述 在乙個完整的專案中,某些功能會反覆的使用。那麼會將功能封裝成函式,當我們要使用功能的時候直接呼叫函式即可 本質 函式就是對功能的封裝 優點 1 簡化 結構,增加了 的復用度 重複使用的程度 2 如果想修改某些功能或者除錯某個bug,只需要修改對應的函式即可 定義函式 格式 def 函式名 引數...

Python學習筆記11 函式

定義函式的時候,我們把引數的名字和位置確定下來,函式的介面定義就完成了。對於函式的呼叫者來說,只需要知道如何傳遞正確的引數,以及函式將返回什麼樣的值就夠了,函式內部的複雜邏輯被封裝起來,呼叫者無需了解。python的函式定義非常簡單,但靈活度卻非常大。除了正常定義的必選引數外,還可以使用預設引數 可...