1. 程式人生 > >python學習日記(正則表示式)

python學習日記(正則表示式)

定義

正則表示式是一個特殊的字元序列,它能幫助你方便的檢查一個字串是否與某種模式匹配。
Python 自1.5版本起增加了re 模組,它提供 Perl 風格的正則表示式模式。
re 模組使 Python 語言擁有全部的正則表示式功能。
compile 函式根據一個模式字串和可選的標誌引數生成一個正則表示式物件。該物件擁有一系列方法用於正則表示式匹配和替換。
re 模組也提供了與這些方法功能完全一致的函式,這些函式使用一個模式字串做為它們的第一個引數。

測試工具

http://tool.chinaz.com/regex/

字元組

字元組 : [字元組]
在同一個位置可能出現的各種字元組成了一個字元組,在正則表示式中用[]表示
字元分為很多類,比如數字、字母、標點等等。
假如你現在要求一個位置
"只能出現一個數字",那麼這個位置上的字元只能是0、1、2...9這10個數之一。

[字元組]:這個位置只能出現一個字元。

[0123456789]

[0-9]

[abcde]

[a-z]

[A-Z]

[0-9a-zA-Z]

[A-z]#A的ASCII碼小於a。

元字元

元字元 匹配內容
. 匹配除換行符以外的所有字元
\w 匹配字母或數字或下劃線
\s 匹配任意的空白符
\d 匹配數字
\n 匹配一個換行符
\t 匹配一個製表符
\b 匹配一個單詞的結尾
^ 匹配字串的開始
$ 匹配字串的結尾
\W 匹配非字母或數字或下劃線
\D 匹配非數字
\S 匹配非空白字元
a|b 匹配字元a或字元b
() 匹配括號內的表示式,也表示一個組
[...] 匹配字元組中的字元
[^...] 匹配除了字元組中字元的所有字元

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

量詞

量詞 用法說明
* 重複零次或更多次
+ 重複一次或更多次
重複零次或一次
{n} 重複n次
{n,} 重複n次或多次
{n,m} 重複n到m次

 

 

 

 

 

 

 

 

 

 

 

 

常用匹配

. ^ $

張. :匹配所有的“張.”的字元

^張. :只從頭開始匹配“張.”

張.$ :只匹配結尾的“張.”

* + ? { }

張.?:?表示重複零次或一次,即只匹配"張"後面一個任意字元

張.*: *表示重複零次或多次,即匹配"李"後面0或多個任意字元

張.+: +表示重複一次或多次,即只匹配"李"後面1個或多個任意字元

張.{1,2}:{1,2}匹配1到2次任意字元

 

注意:前面的*,+,?等都是貪婪匹配,也就是儘可能的匹配,後面加?可使其變成惰性匹配

張.*?:只匹配到一個“張”

 

字符集[][^]

張[三四五六七]*:表示匹配“張”字後面[三四五六七]的字元任意次

張[^李]*:表示匹配一個不是“李”的字元任意次

[\d]:sdfsd123fsd5   表示匹配任意一個數字,匹配四次

([\d]):sdfsd123fsd5  表示匹配任意個數字,匹配到兩個結果

分組 ()與 或 |[^]

身份證號碼是一個長度為15或18個字元的字串,如果是15位則全部由數字組成,首位不能為0;如果是18位,則前17位全部是數字,末位可能是數字或x,下面我們嘗試用正則來表示:

^([1-9]\d{16}[0-9x]|[1-9]\d{14})$           

表示先匹配[1-9]\d{16}[0-9x]如果沒有匹配上就匹配[1-9]\d{14}

注意:長字串先匹配。否則短的字串如果匹配到就不再匹配長的字串

轉義符 \

在正則表示式中,有很多有特殊意義的是元字元,比如\n和\s等,如果要在正則中匹配正常的"\n"而不是"換行符"就需要對"\"進行轉義,變成'\\'。
在python中,無論是正則表示式,還是待匹配的內容,都是以字串的形式出現的,在字串中\也有特殊的含義,本身還需要轉義。
所以如果匹配一次
"\n",字串中要寫成'\\n',那麼正則裡就要寫成"\\\\n",這樣就太麻煩了。這個時候我們就用到了r'\n'這個概念,此時的正則是r'\\n'就可以了。

貪婪匹配

貪婪匹配:在滿足匹配時,匹配儘可能長的字串,預設情況下,採用貪婪匹配

一、正則:<.*>:  待匹配字串:<script>...<script>  結果:<script>...<script>(一條結果)預設為貪婪匹配模式,會匹配儘量長的字串

二、正則:<.*?>: 待匹配字串:<script>...<script>  結果:<script>  <script>(兩條結果)加上?為將貪婪匹配模式轉為非貪婪匹配模式,會匹配儘量短的字串

 

幾個常用的非貪婪匹配Pattern

*? 重複任意次,但儘可能少重複
+? 重複1次或更多次,但儘可能少重複
?? 重複0次或1次,但儘可能少重複
{n,m}? 重複n到m次,但儘可能少重複
{n,}? 重複n次以上,但儘可能少重複
.*?的用法
. 是任意字元
* 是取 0 至 無限長度
? 是非貪婪模式。
何在一起就是 取儘量少的任意字元,一般不會這麼單獨寫,他大多用在:
.*?x

就是取前面任意長度的字元,直到一個x出現

re模組下的常用方法

正則表示式是一個特殊的字元序列,它能幫助你方便的檢查一個字串是否與某種模式匹配。
Python 自1.5版本起增加了re 模組,它提供 Perl 風格的正則表示式模式。
re 模組使 Python 語言擁有全部的正則表示式功能。
compile 函式根據一個模式字串和可選的標誌引數生成一個正則表示式物件。該物件擁有一系列方法用於正則表示式匹配和替換。
re 模組也提供了與這些方法功能完全一致的函式,這些函式使用一個模式字串做為它們的第一個引數

findall()

import re
re = re.findall('a+','sdfa asdf ,sdfsd aa,baba')## 返回所有滿足匹配條件的結果,放在列表裡
print(re)

search()

import re
ret = re.search('^[1-9](\d{14})(\d{2}[0-9x])?$','110105199912122277')#掃描整個字串並返回第一個成功的匹配。
print(ret.group())
print(ret.group(1))#小組號
print(ret.group(2))

match()

import re
re = re.match('a','sa,ssdfsdfa,aaa')#同search,不過在開始處開始搜尋。
print(re)

re.match與re.search的區別

re.match只匹配字串的開始,如果字串開始不符合正則表示式,則匹配失敗,函式返回None;而re.search匹配整個字串,直到找到一個匹配。

記得二者都需group()。

split()

import re
re1 = re.split('a','abcd')
print(re1)
re2 = re.split('[abd]','asdfbannbcd')#先按'a'分割得到''和'bcd',在對''和'bcd'分別按'b'分割
re3 = re.split('[ab]','asdfbannbcd')
re4 = re.split('[a]','asdfbannbcd')
#--首尾被切才為空
print(re4)
print(re3)
print(re2)

sub()、subn()

import re
re1 = re.sub('a','哈哈','sdfasdfsdfaaasdfaaaa',4)#可選替換幾次,預設不填則全部替換
print(re1)
re2 = re.subn('a','哈哈','afsdfhj,sdjfkldfakjsldfka',2)#返回元組,替換的結果和次數
print(re2)

complie()

compile 函式用於編譯正則表示式,生成一個正則表示式( Pattern )物件,供 match() 和 search() 這兩個函式使用。

o = re.compile('\d{3}')
x = o.search('123sdfasdfdsf1adf2323')
print(x)#
print(x.group())#不是findall記得加group()方法

finditer()

和 findall 類似,在字串中找到正則表示式所匹配的所有子串,並把它們作為一個迭代器返回。

import re
r = re.finditer('[a-z]','asdf456sdf6adf')
for i in r:
    print(i.group(),end=' ')

注意:

1、findall的優先順序查詢:

import re
r = re.findall('one (apple|watermelon) left','There is only one apple left')#findall優先返回匹配結果組裡面的內容
print(r)
r1 = re.findall('one (?:apple|watermelon) left','There is only one apple left')#取消優先權  " ?: "
print(r1)

2、split的優先順序查詢:

import re
r = re.split('\d','aaa1bb2c3')
print(r)
r1 = re.split('(\d)','aaa1bb2c3')#保留切所匹配的項  “()”
print(r1)

一、校驗數字的表示式

數字:^[0-9]*$
n位的數字:^\d{n}$
至少n位的數字:^\d{n,}$
m-n位的數字:^\d{m,n}$
零和非零開頭的數字:^(0|[1-9][0-9]*)$
非零開頭的最多帶兩位小數的數字:^([1-9][0-9]*)+(\.[0-9]{1,2})?$
帶1-2位小數的正數或負數:^(\-)?\d+(\.\d{1,2})$
正數、負數、和小數:^(\-|\+)?\d+(\.\d+)?$
有兩位小數的正實數:^[0-9]+(\.[0-9]{2})?$
有1~3位小數的正實數:^[0-9]+(\.[0-9]{1,3})?$
非零的正整數:^[1-9]\d*$ 或 ^([1-9][0-9]*){1,3}$ 或 ^\+?[1-9][0-9]*$
非零的負整數:^\-[1-9][]0-9"*$ 或 ^-[1-9]\d*$
非負整數:^\d+$ 或 ^[1-9]\d*|0$
非正整數:^-[1-9]\d*|0$ 或 ^((-\d+)|(0+))$
非負浮點數:^\d+(\.\d+)?$ 或 ^[1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0$
非正浮點數:^((-\d+(\.\d+)?)|(0+(\.0+)?))$ 或 ^(-([1-9]\d*\.\d*|0\.\d*[1-9]\d*))|0?\.0+|0$
正浮點數:^[1-9]\d*\.\d*|0\.\d*[1-9]\d*$ 或 ^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$
負浮點數:^-([1-9]\d*\.\d*|0\.\d*[1-9]\d*)$ 或 ^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$
浮點數:^(-?\d+)(\.\d+)?$ 或 ^-?([1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0)$
校驗數字的表示式

二、校驗字元的表示式

漢字:^[\u4e00-\u9fa5]{0,}$
英文和數字:^[A-Za-z0-9]+$ 或 ^[A-Za-z0-9]{4,40}$
長度為3-20的所有字元:^.{3,20}$
由26個英文字母組成的字串:^[A-Za-z]+$
由26個大寫英文字母組成的字串:^[A-Z]+$
由26個小寫英文字母組成的字串:^[a-z]+$
由數字和26個英文字母組成的字串:^[A-Za-z0-9]+$
由數字、26個英文字母或者下劃線組成的字串:^\w+$ 或 ^\w{3,20}$
中文、英文、數字包括下劃線:^[\u4E00-\u9FA5A-Za-z0-9_]+$
中文、英文、數字但不包括下劃線等符號:^[\u4E00-\u9FA5A-Za-z0-9]+$ 或 ^[\u4E00-\u9FA5A-Za-z0-9]{2,20}$
可以輸入含有^%&',;=?$\"等字元:[^%&',;=?$\x22]+
禁止輸入含有~的字元:[^~\x22]+
校驗字元的表示式

三、特殊需求表示式

Email地址:^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$
域名:[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(/.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+/.?
InternetURL:[a-zA-z]+://[^\s]* 或 ^http://([\w-]+\.)+[\w-]+(/[\w-./?%&=]*)?$
手機號碼:^(13[0-9]|14[5|7]|15[0|1|2|3|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])\d{8}$
電話號碼("XXX-XXXXXXX""XXXX-XXXXXXXX""XXX-XXXXXXX""XXX-XXXXXXXX""XXXXXXX""XXXXXXXX):^(\(\d{3,4}-)|\d{3.4}-)?\d{7,8}$
國內電話號碼(0511-4405222、021-87888822):\d{3}-\d{8}|\d{4}-\d{7}
電話號碼正則表示式(支援手機號碼,3-4位區號,7-8位直播號碼,1-4位分機號): ((\d{11})|^((\d{7,8})|(\d{4}|\d{3})-(\d{7,8})|(\d{4}|\d{3})-(\d{7,8})-(\d{4}|\d{3}|\d{2}|\d{1})|(\d{7,8})-(\d{4}|\d{3}|\d{2}|\d{1}))$)
身份證號(15位、18位數字),最後一位是校驗位,可能為數字或字元X:(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)
帳號是否合法(字母開頭,允許5-16位元組,允許字母數字下劃線):^[a-zA-Z][a-zA-Z0-9_]{4,15}$
密碼(以字母開頭,長度在6~18之間,只能包含字母、數字和下劃線):^[a-zA-Z]\w{5,17}$
強密碼(必須包含大小寫字母和數字的組合,不能使用特殊字元,長度在 8-10 之間):^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])[a-zA-Z0-9]{8,10}$
強密碼(必須包含大小寫字母和數字的組合,可以使用特殊字元,長度在8-10之間):^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,10}$
日期格式:^\d{4}-\d{1,2}-\d{1,2}
一年的12個月(01~09和1~12):^(0?[1-9]|1[0-2])$
一個月的31天(01~09和1~31):^((0?[1-9])|((1|2)[0-9])|30|31)$
錢的輸入格式:
有四種錢的表示形式我們可以接受:"10000.00""10,000.00", 和沒有 """10000""10,000":^[1-9][0-9]*$
這表示任意一個不以0開頭的數字,但是,這也意味著一個字元"0"不通過,所以我們採用下面的形式:^(0|[1-9][0-9]*)$
一個0或者一個不以0開頭的數字.我們還可以允許開頭有一個負號:^(0|-?[1-9][0-9]*)$
這表示一個0或者一個可能為負的開頭不為0的數字.讓使用者以0開頭好了.把負號的也去掉,因為錢總不能是負的吧。下面我們要加的是說明可能的小數部分:^[0-9]+(.[0-9]+)?$
必須說明的是,小數點後面至少應該有1位數,所以"10."是不通過的,但是 "10""10.2" 是通過的:^[0-9]+(.[0-9]{2})?$
這樣我們規定小數點後面必須有兩位,如果你認為太苛刻了,可以這樣:^[0-9]+(.[0-9]{1,2})?$
這樣就允許使用者只寫一位小數.下面我們該考慮數字中的逗號了,我們可以這樣:^[0-9]{1,3}(,[0-9]{3})*(.[0-9]{1,2})?$
1到3個數字,後面跟著任意個 逗號+3個數字,逗號成為可選,而不是必須:^([0-9]+|[0-9]{1,3}(,[0-9]{3})*)(.[0-9]{1,2})?$
備註:這就是最終結果了,別忘了"+"可以用"*"替代如果你覺得空字串也可以接受的話(奇怪,為什麼?)最後,別忘了在用函式時去掉去掉那個反斜槓,一般的錯誤都在這裡
xml檔案:^([a-zA-Z]+-?)+[a-zA-Z0-9]+\\.[x|X][m|M][l|L]$
中文字元的正則表示式:[\u4e00-\u9fa5]
雙位元組字元:[^\x00-\xff] (包括漢字在內,可以用來計算字串的長度(一個雙位元組字元長度計2,ASCII字元計1))
空白行的正則表示式:\n\s*\r (可以用來刪除空白行)
HTML標記的正則表示式:<(\S*?)[^>]*>.*?|<.*? /> ( 首尾空白字元的正則表示式:^\s*|\s*$或(^\s*)|(\s*$) (可以用來刪除行首行尾的空白字元(包括空格、製表符、換頁符等等),非常有用的表示式)
騰訊QQ號:[1-9][0-9]{4,} (騰訊QQ號從10000開始)
中國郵政編碼:[1-9]\d{5}(?!\d) (中國郵政編碼為6位數字)
IP地址:((?:(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d)\\.){3}(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d))
特殊需求表示式

 

pass