1. 程式人生 > >python基礎之 正則表達式,re模塊

python基礎之 正則表達式,re模塊

方便 轉義 python pan imp 解決 進行 nbsp 每一個

正則表達式:是字符串的規則,只是檢測字符串是否符合條件的規則而已
    1.檢測某一段字符串是否符合規則
    2.將符合規則的匹配出來
re模塊:是用來操作正則表達式的

2.正則表達式組成

字符組:[] 一個字符組描述的是一個位置上的字符規則,但是不能從大到小來規定範圍,字符組內所有的範圍都是ascii來排序的,字符組更靈活一點
  [0-9] 匹配一個數字範圍
  [a-z] 匹配一個小寫字母
  [A-Z] 匹配一個大寫字母
  [A-Za-z0-9] 匹配英文字母和大小寫 左邊必須是ascii最小的

  註意:遇到在字符組當中的-是有特殊意義的,如果想取消
-的特殊意義,要轉義一下   例如:[1-2] 是匹配不是1就是2的數據,但是我想匹配1,-,2那?需要轉義一下[1\-2] 元字符:匹配的一個字符的內容   \d: 使用\d表示匹配任意從0-9的數字,使用字符組能匹配到一個固定的範圍,但是\d表示的時從0-9太固定 \w:匹配所有的數字字母下劃線,標識符 -t:匹配tab制表符 \n:匹配換行符 \s:匹配所有的空格換行制表符 \b:表示一個單詞的邊界,要匹配以XX結尾的單詞 反義詞: \W:除了數字字母下劃線的所有 \D:除了數字之外的所有 \S:除了空白之外的所有 .:匹配換行符之外的所有字符 非字符組:[
^123] 除了123的都匹配 ‘^’必須和[]組合才叫非字符組 開始符^ 結束符$   一個字符串只有一個開始和一個結束,^永遠在一個規則的最前面,$永遠在一個字符串的最末尾   ^hello$ -->匹配一個hello,規定了這個字符串的長度,在字符串檢測的時候通常加上^和$符號   [^123] :匹配的是不以123開頭的 | 或的意思,豎杠的左邊或右邊是一個規則,永遠把相對長的規則放在左邊 分組:()--> www\.(baidu|oldboy)\.com 量詞:表示的是匹配的次數,在量詞的範圍內盡可能的多的匹配,叫貪婪匹配    {n} 表示出現n次    {n,} 表示出至少出現n次    {n,m}表示存出現n
-m次    ?:匹配額0次或1次    +:匹配1次或多次    *:匹配0次或多次   ?和+的範圍等於*的範圍    匹配電話號碼:^1[3-9]\d{9}$: 匹配整數:^[1-9]\d*|0& 匹配小數:\d+\.\d+ 匹配整數或者小數:\d+(\.\d+)? -->裏面的()是分組的意思,?表示要不()裏面的一起出現,不要就都不出現 \d+\.?\d* 匹配15位身份證號碼:^[1-9]\d{14}$ 匹配18位身份證號碼:^[1-9]\d{16}[\dx]$ #轉義字符:在字符串外部加上一個r來不轉義 貪婪匹配:盡可能的多匹配 a.*x 回溯算法 惰性匹配:盡可能的少匹配 .*? ,兩個量詞同時出現時表示非貪婪 a.*?x 從a開始匹配,遇到一個x就停止       就是量詞後面加上?就是惰性匹配,匹配到第一個就停止

re模塊

import re
s=kobe123jordan46

re.findall(pattern,string,flags=0)
  ret = re.findall(\d+,s)
  print()
  查看所有,返回一個列表
  註意:在正則條件不一樣的情況下返回的內容不一樣 \d+是貪婪的匹配所有數字組成一個字符串

re.search(pattern,string,flags=0)
  ret =re.search(\d+,s)
  print(ret)
  print(ret.group())
  返回一個結果對象或結果集
  通過group()取值只取到第一個,如果沒有符合條件的group就會報錯,一般用if判斷一下是否為空

re.match(pattern,string,flags=0)
  ret = re.match(\s+,s)
  print(ret)
  返回一個結果對象或結果集
  使用match的話,相當於在正則表達式前面加上^,在程序裏面匹配的是^\s,是找以字符串開頭的,沒有的話就返回None
  使用search完全可以代替match,只要在search的表達式前面加上^就可以
  re.search(^\s+,kobe123) == re.match(\s+,kobe123)

re.sub(pattern,repl,string,count=0)
  ret = re.sub(\d+,sb,s,count=1)
  print(ret)
  count不寫的話默認替換所有,返回一個字符串
  
re.subn(pattern,repl,string,count=0)
  ret = re.sun(\d+,sb,s)
  print(ret)
  默認返回一個元組,並且返回被替換了多少次
re.split(pattern,string,maxsplit=1)
  ret = re.split(\d+,s,maxsplit=1)
  print(ret)
  默認返回一個列表,不加maxsplit就全部分割

re.compile(pattern)
  par = re.compile(\d+)
  ret = par.findall(s)
  print(ret)
  對於一個經常重復使用的正則表達式,我們可以先進行一次編譯,之後只要在使用這個表達式就直接拿出來使用
  就好了,這樣做節省時間和及其資源,減少解析時間個轉成機器碼的時間
  re.compile()是一個優化函數,提升執行效率減少不必要的時間和性能的開銷

re.finditer(pattern,string)
  par = re.compile(\d+)
  ret = par.finditer(kob123kobe123kobe123kobe123*200) 
  for item in ret:
    print(item.group())
  返回的是一個生成器結果集,通過group方法取出每一個數據
  看到iter應該能想到是生成器原理,通過循環每次使生成器返回一個數據,這樣和使用生成器讀取大文件一樣,節省內存
  能夠提前編譯一個正則表達式,當同一個正則表達式被多次使用時,可以直接使用節省時間


分組
  s= """
    <h1>哇哈哈哈<h1>
    <h2>哈哈哈哈<h2>
    <title>科比</title>
   """
  findall()和分組:分組在findall當中會默認的優先被顯示出來
    ret = re.findall(>\w+<,r<title>科比<\title>)
    print(ret[0].strip(<>))
    分組在findall當中會默認的優先被顯示出來,如果不想優先顯示出來就在分組中添加(?:正則規則)表示取消這個正則的優先顯示
  
            ret = re.findall(>\w+<,r<title>科比<\title>)
            print(ret[0].strip(<>))
            ret = re.findall(>(\w+)<,r<title>科比<\title>)
            print(ret)  # findall永遠優先顯示分組中的內容
            ret = re.findall(www\.(?:baidu|nba)\.com,rwww.baidu.com)
            print(ret)
            ret = re.findall(\d+(?:\.\d+)?,r1.23+2.34)
            print(ret)
  split()和分組:會保留被切掉的在分組中內容    
            ret = re.split(\d(\d),alex84wusir73)
            print(ret)
  search()和分組:不受到分組的影響
    
            ret = re.search(r<(\w+)>(\w+)<\\(\w+)>,r<title>科比<\title>)
            print(ret.group(0))  # 不受到分組的影響
            print(ret.group(1))
            print(ret.group(2))
分組命名
  #分組命名就是把一個要匹配的東西取一個名字,在以後調用返回的時候回方便,直接使用名字就OK了
  #如果有取值的有兩個相同的名字的話可以復制為(?P=a),必須要寫的分組裏面,不然的不能叫分組命名了
     ret = re.search(r<(?P<tab1>\w+)>(?P<content>\w+)<\\(\w+)>,r<title>科比<\title>)
            print(ret.group(0))  # 不受到分組的影響
            print(ret.group(tab1))  # 不受到分組的影響
            print(ret.group(content))  # 不受到分組的影響
     特殊的需求:把這個字符串全部匹配出來<h1>wahaha</h2></h1>
            par = <\w+>.*?</\w+>
            ret = re.search(<(?P<tag>\w+)>.*</(?P=tag)>,<h1>wahaha</h2></h1></h3>)
            print(ret.group())
            par = <\w+>.*?</\w+>
            ret = re.search(r<(\w+)>.*</\1>,<h1>wahaha</h2></h1></h3>)
            print(ret.group())
    當我們要匹配的內容混在不想匹配的內容中
    只能把不想要的也匹配出來,然後去掉不想要的就是想要的
    下列我只想取整數部分
    ret = re.findall(\d+\.\d+|(\d+),1-2*(60+(-40.35/5)-(-4*3))) #取出來不包含40.35,但是包含"",因為findall遇到分組是優先匹配,所以匹配到小數就放棄,但是必須得返回一個元素,就返回""
    ret = re.findall(\d+\.\d+|\d+,1-2*(60+(-40.35/5)-(-4*3)))  #取出來的包含40.35
    ret.remove(‘‘)
    print(ret)
遇見分組
    findall 優先顯示分組中的內容
    split   保留被切掉的分組內的內容
    search  可以通過組的索引取值
    取消分組的特殊行為(?:正則)
常見的使用正則解決問題的方式#
  1.把整個結構描述下來,對想要的進行分組#
  2.把不想要的也匹配出來,然後用手段刪掉

常見的正則表達式

1. 數字:^[0-9]*$
2. n位的數字:^\d{n}$
3. 至少n位的數字:^\d{n,}$
4. m-n位的數字:^\d{m,n}$
5. 零和非零開頭的數字:^(0|[1-9][0-9]*)$
6. 非零開頭的最多帶兩位小數的數字:^([1-9][0-9]*)+(.[0-9]{1,2})?$
7. 帶1-2位小數的正數或負數:^(\-)?\d+(\.\d{1,2})?$
8. 正數、負數、和小數:^(\-|\+)?\d+(\.\d+)?$
9. 有兩位小數的正實數:^[0-9]+(.[0-9]{2})?$
10. 有1~3位小數的正實數:^[0-9]+(.[0-9]{1,3})?$
11. 非零的正整數:^[1-9]\d*$ 或 ^([1-9][0-9]*){1,3}$ 或 ^\+?[1-9][0-9]*$
12. 非零的負整數:^\-[1-9][]0-9"*$ 或 ^-[1-9]\d*$
13. 非負整數:^\d+$ 或 ^[1-9]\d*|0$
14. 非正整數:^-[1-9]\d*|0$ 或 ^((-\d+)|(0+))$
15. 非負浮點數:^\d+(\.\d+)?$ 或 ^[1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0$
16. 非正浮點數:^((-\d+(\.\d+)?)|(0+(\.0+)?))$ 或 ^(-([1-9]\d*\.\d*|0\.\d*[1-9]\d*))|0?\.0+|0$
17. 正浮點數:^[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]*))$
18. 負浮點數:^-([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]*)))$
19. 浮點數:^(-?\d+)(\.\d+)?$ 或 ^-?([1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0)$
2.校驗字符的表達式
1. 漢字:^[\u4e00-\u9fa5]{0,}$
2. 英文和數字:^[A-Za-z0-9]+$ 或 ^[A-Za-z0-9]{4,40}$
3. 長度為3-20的所有字符:^.{3,20}$
4. 由26個英文字母組成的字符串:^[A-Za-z]+$
5. 由26個大寫英文字母組成的字符串:^[A-Z]+$
6. 由26個小寫英文字母組成的字符串:^[a-z]+$
7. 由數字和26個英文字母組成的字符串:^[A-Za-z0-9]+$
8. 由數字、26個英文字母或者下劃線組成的字符串:^\w+$ 或 ^\w{3,20}$
9. 中文、英文、數字包括下劃線:^[\u4E00-\u9FA5A-Za-z0-9_]+$
10. 中文、英文、數字但不包括下劃線等符號:^[\u4E00-\u9FA5A-Za-z0-9]+$ 或 ^[\u4E00-\u9FA5A-Za-z0-9]{2,20}$
11. 可以輸入含有^%&,;=?$\"等字符:[^%&,;=?$\x22]+
12. 禁止輸入含有~的字符:[^~\x22]+
3.特殊需求表達式
1. Email地址:^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$
2. 域名:[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(/.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+/.?
3. InternetURL:[a-zA-z]+://[^\s]* 或 ^http://([\w-]+\.)+[\w-]+(/[\w-./?%&=]*)?$
4. 手機號碼(可根據目前國內收集號擴展前兩位開頭號碼):^(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}$
5. 電話號碼("XXX-XXXXXXX""XXXX-XXXXXXXX""XXX-XXXXXXX""XXX-XXXXXXXX""XXXXXXX""XXXXXXXX):^(\(\d{3,4}-)|\d{3.4}-)?\d{7,8}$
6. 國內電話號碼(0511-4405222、021-87888822):\d{3}-\d{8}|\d{4}-\d{7}
7.15位身份證號:^[1-9]\d{5}\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{2}$
8.18位身份證號:^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$
9. 帳號是否合法(字母開頭,允許5-16字節,允許字母數字下劃線):^[a-zA-Z][a-zA-Z0-9_]{4,15}$
10. 密碼(以字母開頭,長度在6~18之間,只能包含字母、數字和下劃線):^[a-zA-Z]\w{5,17}$
11. 強密碼(必須包含大小寫字母和數字的組合,不能使用特殊字符,長度在8-10之間):^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,10}$
12. 日期格式:^\d{4}-\d{1,2}-\d{1,2}
13. 一年的12個月(01~09和1~12):^(0?[1-9]|1[0-2])$
14. 一個月的31天(01~09和1~31):^((0?[1-9])|((1|2)[0-9])|30|31)$
15. 錢的輸入格式:
(1)有四種錢的表示形式我們可以接受:"10000.00""10,000.00", 和沒有 """10000""10,000":^[1-9][0-9]*$
(2)這表示任意一個不以0開頭的數字,但是,這也意味著一個字符"0"不通過,所以我們采用下面的形式:^(0|[1-9][0-9]*)$
(3)一個0或者一個不以0開頭的數字.我們還可以允許開頭有一個負號:^(0|-?[1-9][0-9]*)$
(4)這表示一個0或者一個可能為負的開頭不為0的數字.讓用戶以0開頭好了.把負號的也去掉,因為錢總不能是負的吧.下面我們要加的是說明可能的小數部分:^[0-9]+(.[0-9]+)?$
(5)必須說明的是,小數點後面至少應該有1位數,所以"10."是不通過的,但是 "10""10.2" 是通過的:^[0-9]+(.[0-9]{2})?$
(6)這樣我們規定小數點後面必須有兩位,如果你認為太苛刻了,可以這樣:^[0-9]+(.[0-9]{1,2})?$
(7)這樣就允許用戶只寫一位小數.下面我們該考慮數字中的逗號了,我們可以這樣:^[0-9]{1,3}(,[0-9]{3})*(.[0-9]{1,2})?$
(8)1到3個數字,後面跟著任意個 逗號+3個數字,逗號成為可選,而不是必須:^([0-9]+|[0-9]{1,3}(,[0-9]{3})*)(.[0-9]{1,2})?$
備註:這就是最終結果了,別忘了"+"可以用"*"替代如果你覺得空字符串也可以接受的話(奇怪,為什麽?)最後,別忘了在用函數時去掉去掉那個反斜杠,一般的錯誤都在這裏
16. xml文件:^([a-zA-Z]+-?)+[a-zA-Z0-9]+\\.[x|X][m|M][l|L]$
17. 中文字符的正則表達式:[\u4e00-\u9fa5]
18. 雙字節字符:[^\x00-\xff] (包括漢字在內,可以用來計算字符串的長度(一個雙字節字符長度計2,ASCII字符計1))
19. 空白行的正則表達式:\n\s*\r (可以用來刪除空白行)
20. HTML標記的正則表達式:<(\S*?)[^>]*>.*?</\1>|<.*? /> (網上流傳的版本太糟糕,上面這個也僅僅能部分,對於復雜的嵌套標記依舊無能為力)
21. 首尾空白字符的正則表達式:^\s*|\s*$或(^\s*)|(\s*$) (可以用來刪除行首行尾的空白字符(包括空格、制表符、換頁符等等),非常有用的表達式)
22. 騰訊QQ號:[1-9][0-9]{4,} (騰訊QQ號從10000開始)
23. 中國郵政編碼:[1-9]\d{5}(?!\d) (中國郵政編碼為6位數字)
24. IP地址:\d+\.\d+\.\d+\.\d+ (提取IP地址時有用)
25. IP地址:((?:(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d)\\.){3}(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d))

常見的正則表達式

python基礎之 正則表達式,re模塊