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:
# -*- 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 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的函式定義非常簡單,但靈活度卻非常大。除了正常定義的必選引數外,還可以使用預設引數 可...