python學習日記(正則表示式)
定義
正則表示式是一個特殊的字元序列,它能幫助你方便的檢查一個字串是否與某種模式匹配。
Python 自1.5版本起增加了re 模組,它提供 Perl 風格的正則表示式模式。
re 模組使 Python 語言擁有全部的正則表示式功能。
compile 函式根據一個模式字串和可選的標誌引數生成一個正則表示式物件。該物件擁有一系列方法用於正則表示式匹配和替換。
re 模組也提供了與這些方法功能完全一致的函式,這些函式使用一個模式字串做為它們的第一個引數。
測試工具
字元組
字元組 : [字元組] 在同一個位置可能出現的各種字元組成了一個字元組,在正則表示式中用[]表示 字元分為很多類,比如數字、字母、標點等等。 假如你現在要求一個位置"只能出現一個數字",那麼這個位置上的字元只能是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