24-[模塊]-re
1、引入re
請從以下文件裏取出所有的手機號
姓名 地區 身高 體重 電話 況詠蜜 北京 171 48 13651054608 王心顏 上海 169 46 13813234424 馬纖羽 深圳 173 50 13744234523 喬亦菲 廣州 172 52 15823423525 羅夢竹 北京 175 49 18623423421 劉諾涵 北京 170 48 18623423765 嶽妮妮 深圳177 54 18835324553 賀婉萱 深圳 174 52 18933434452 葉梓萱 上海 171 49 18042432324 杜姍姍 北京 167 49 13324523342
(1)普通版本
# -*- coding:utf-8 -*- phone = [] with open(‘phone‘, ‘r‘,encoding=‘utf-8‘) as f: for line in f: line1 = line.split()for i in line1: if i.startswith(‘1‘) and len(i) == 11: phone.append(i) print(phone)
(2)文藝版本
# 拆包 # -*- coding:utf-8 -*- phone_list = [] with open(‘phone‘, ‘r‘,encoding=‘utf-8‘) as f: for line in f: # 拆包 name,city,height,weight,phone = line.split()if phone.startswith(‘1‘) and len(phone) == 11: phone_list.append(phone) print(phone_list)
(3)裝B版本
2.正則表達式
- 正則表達式本質上是一門語言,它不從屬與Python!Python只是將他人寫好的正則引擎集成到了語言內部,大多數編程語言都是這麽幹的!
- 正則表達式誕生的時間很長,應用非常廣泛,是業界公認的字符串匹配工具。雖然有不同版本的內部引擎,但基本通用,也就是說,你在Python內寫的正則表達式,可以移植到Linux的shell,Java語言等任何支持正則的場景中去。
- 正則表達式默認從左往右匹配。
- 正則表達式默認是貪婪模式。
- 正則表達式默認在匹配到了內容後,則終止匹配,不繼續匹配。
- 對同一個問題,編寫的正則表達式不是唯一的!
3.常用正則表達式
(1)校驗數字的相關表達式:
功能 | 表達式 |
---|---|
數字 | ^[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]\d*$ |
非負整數 | ^\d+$ |
非正整數 | ^-[1-9]\d*|0$ |
非負浮點數 | ^\d+(\.\d+)?$ |
非正浮點數 | ^((-\d+(\.\d+)?)|(0+(\.0+)?))$ |
正浮點數 | ^[1-9]\d*\.\d*|0\.\d*[1-9]\d*$ |
負浮點數 | ^-([1-9]\d*\.\d*|0\.\d*[1-9]\d*)$ |
浮點數 | ^(-?\d+)(\.\d+)?$ |
(2)校驗字符的相關表達式:
功能 | 表達式 |
---|---|
漢字 | ^[\u4e00-\u9fa5]{0,}$ |
英文和數字 | ^[A-Za-z0-9]+$ |
長度為3-20的所有字符 | ^.{3,20}$ |
由26個英文字母組成的字符串 | ^[A-Za-z]+$ |
由26個大寫英文字母組成的字符串 | ^[A-Z]+$ |
由26個小寫英文字母組成的字符串 | ^[a-z]+$ |
由數字和26個英文字母組成的字符串 | ^[A-Za-z0-9]+$ |
由數字、26個英文字母或者下劃線組成的字符串 | ^\w+$ |
中文、英文、數字包括下劃線 | ^[\u4E00-\u9FA5A-Za-z0-9_]+$ |
中文、英文、數字但不包括下劃線等符號 | ^[\u4E00-\u9FA5A-Za-z0-9]+$ |
可以輸入含有^%&’,;=?$\” 等字符 |
[^%&’,;=?$\x22]+ |
禁止輸入含有~ 的字符 |
[^~\x22]+ |
(3)特殊場景的表達式:
功能 | 表達式 |
---|---|
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}$ |
國內電話號碼 | \d{3}-\d{8}|\d{4}-\d{7} (0511-4405222、021-87888822) |
身份證號 | ^\d{15}|\d{18}$ (15位、18位數字) |
短身份證號碼 | ^([0-9]){7,18}(x|X)?$ 或 ^\d{8,18}|[0-9x]{8,18}|[0-9X]{8,18}?$ (數字、字母x結尾) |
帳號是否合法 | ^[a-zA-Z][a-zA-Z0-9_]{4,15}$ (字母開頭,允許5-16字節,允許字母數字下劃線) |
密碼 | ^[a-zA-Z]\w{5,17}$ (以字母開頭,長度在6~18之間,只能包含字母、數字和下劃線) |
強密碼 | ^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,10}$ (必須包含大小寫字母和數字的組合,不能使用特殊字符,長度在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)$ |
xml文件 | ^([a-zA-Z]+-?)+[a-zA-Z0-9]+\\.[x|X][m|M][l|L]$ |
雙字節字符 | [^\x00-\xff] (包括漢字在內,可以用來計算字符串的長度(一個雙字節字符長度計2,ASCII字符計1)) |
空白行的正則表達式 | \n\s*\r (可以用來刪除空白行) |
HTML標記的正則表達式 | <(\S*?)[^>]*>.*?</\1>|<.*? /> (對於復雜的嵌套標記依舊無能為力) |
首尾空白字符的正則表達式 | ^\s*|\s*$或(^\s*)|(\s*$) (可以用來刪除行首行尾的空白字符(包括空格、制表符、換頁符等等)) |
騰訊QQ號 | [1-9][0-9]{4,} (騰訊QQ號從10000開始) |
中國郵政編碼 | [1-9]\d{5}(?!\d) (中國郵政編碼為6位數字) |
IP地址提取 | \d+\.\d+\.\d+\.\d+ (提取IP地址時有用) |
IP地址合法性判斷 | ((?:(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d)\\.){3}(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d)) |
4、re模塊
正則表達式就是字符串的匹配規則,在多數編程語言裏都有相應的支持,python裏對應的模塊是re
常用的表達式規則
‘.‘ 默認匹配除\n之外的任意一個字符,若指定flag DOTALL,則匹配任意字符,包括換行 ‘^‘ 匹配字符開頭,若指定flags MULTILINE,這種也可以匹配上(r"^a","\nabc\neee",flags=re.MULTILINE) ‘$‘ 匹配字符結尾, 若指定flags MULTILINE ,re.search(‘foo.$‘,‘foo1\nfoo2\n‘,re.MULTILINE).group() 會匹配到foo1 ‘*‘ 匹配*號前的字符0次或多次, re.search(‘a*‘,‘aaaabac‘) 結果‘aaaa‘ ‘+‘ 匹配前一個字符1次或多次,re.findall("ab+","ab+cd+abb+bba") 結果[‘ab‘, ‘abb‘] ‘?‘ 匹配前一個字符1次或0次 ,re.search(‘b?‘,‘alex‘).group() 匹配b 0次 ‘{m}‘ 匹配前一個字符m次 ,re.search(‘b{3}‘,‘alexbbbs‘).group() 匹配到‘bbb‘ ‘{n,m}‘ 匹配前一個字符n到m次,re.findall("ab{1,3}","abb abc abbcbbb") 結果‘abb‘, ‘ab‘, ‘abb‘] ‘|‘ 匹配|左或|右的字符,re.search("abc|ABC","ABCBabcCD").group() 結果‘ABC‘ ‘(...)‘ 分組匹配, re.search("(abc){2}a(123|45)", "abcabca456c").group() 結果為‘abcabca45‘ ‘\A‘ 只從字符開頭匹配,re.search("\Aabc","alexabc") 是匹配不到的,相當於re.match(‘abc‘,"alexabc") 或^ ‘\Z‘ 匹配字符結尾,同$ ‘\d‘ 匹配數字0-9 ‘\D‘ 匹配非數字 ‘\w‘ 匹配[A-Za-z0-9] ‘\W‘ 匹配非[A-Za-z0-9] ‘s‘ 匹配空白字符、\t、\n、\r , re.search("\s+","ab\tc1\n3").group() 結果 ‘\t‘ ‘(?P<name>...)‘ 分組匹配 re.search("(?P<province>[0-9]{4})(?P<city>[0-9]{2})(?P<birthday>[0-9]{4})","371481199306143242").groupdict("city") 結果{‘province‘: ‘3714‘, ‘city‘: ‘81‘, ‘birthday‘: ‘1993‘}
5.re的匹配語法
re的匹配語法有以下幾種
- re.match 從頭開始匹配
- re.search 匹配包含
- re.findall 把所有匹配到的字符放到以列表中的元素返回
- re.split 以匹配到的字符當做列表分隔符
- re.sub 匹配字符並替換
- re.fullmatch 全部匹配
re.compile(pattern, flags=0)
Compile a regular expression pattern into a regular expression object, which can be used for matching using its match(), search() and other methods, described below.
The sequence
prog = re.compile(pattern)
result = prog.match(string)
is equivalent to
result = re.match(pattern, string)
but using re.compile() and saving the resulting regular expression object for reuse is more efficient when the expression will be used several times in a single program.
re.match(pattern, string, flags=0)
從起始位置開始根據模型去字符串中匹配指定內容,匹配單個
- pattern 正則表達式
- string 要匹配的字符串
- flags 標誌位,用於控制正則表達式的匹配方式
import re
obj = re.match(‘\d+‘, ‘123uuasf‘)
if obj:
print obj.group()
Flags標誌符
- re.I(re.IGNORECASE): 忽略大小寫(括號內是完整寫法,下同)
- M(MULTILINE): 多行模式,改變‘^‘和‘$‘的行為
- S(DOTALL): 改變‘.‘的行為,make the ‘.‘ special character match any character at all, including a newline; without this flag, ‘.‘ will match anything except a newline.
- X(re.VERBOSE) 可以給你的表達式寫註釋,使其更可讀,下面這2個意思一樣
a = re.compile(r"""\d + # the integral part
\. # the decimal point
\d * # some fractional digits""",
re.X)
b = re.compile(r"\d+\.\d*")
re.search(pattern, string, flags=0)
根據模型去字符串中匹配指定內容,匹配單個
import re
obj = re.search(‘\d+‘, ‘u123uu888asf‘)
if obj:
print obj.group()
re.findall(pattern, string, flags=0)
match and search均用於匹配單值,即:只能匹配字符串中的一個,如果想要匹配到字符串中所有符合條件的元素,則需要使用 findall。
import re
obj = re.findall(‘\d+‘, ‘fa123uu888asf‘)
print obj
re.sub(pattern, repl, string, count=0, flags=0)
用於替換匹配的字符串
>>>re.sub(‘[a-z]+‘,‘sb‘,‘武配齊是abc123‘,)
>>> re.sub(‘\d+‘,‘|‘, ‘alex22wupeiqi33oldboy55‘,count=2)
‘alex|wupeiqi|oldboy55‘
相比於str.replace功能更加強大
re.split(pattern, string, maxsplit=0, flags=0)
>>>s=‘9-2*5/3+7/3*99/4*2998+10*568/14‘
>>>re.split(‘[\*\-\/\+]‘,s)
[‘9‘, ‘2‘, ‘5‘, ‘3‘, ‘7‘, ‘3‘, ‘99‘, ‘4‘, ‘2998‘, ‘10‘, ‘568‘, ‘14‘]
>>> re.split(‘[\*\-\/\+]‘,s,3)
[‘9‘, ‘2‘, ‘5‘, ‘3+7/3*99/4*2998+10*568/14‘]
re.fullmatch(pattern, string, flags=0)
整個字符串匹配成功就返回re object, 否則返回None
re.fullmatch(‘\w+@\w+\.(com|cn|edu)‘,"[email protected]")
3
4
24-[模塊]-re